How much introspection is implementation dependent?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • James Stroud

    #1

    How much introspection is implementation dependent?

    Hello,

    I wanted to automagically generate an instance of a class from a
    dictionary--which might be generated from yaml or json. I came up with this:


    # automagical constructor
    def construct(cls, adict):
    dflts = cls.__init__.im _func.func_defa ults
    vnames = cls.__init__.im _func.func_code .co_varnames

    argnames = vnames[1:-len(dflts)]
    argvals = [adict.pop(n) for n in argnames]

    return cls(*argvals, **adict)


    I'm wondering, I did a lot of introspection here. How much of this
    introspection can I count on in other implementations . Is this a
    byproduct of CPython? Will all classes have these attributes, even
    classes imported from shared objects? It would be nice to rely on these
    things.

    <asideI know pyaml advertises the ability to do this, but, much to my
    annoyance, I found it never actually calls __init__() of YAMLObject
    subclasses, but this is another topic altogether. </aside>

    Below is the example (optional reading).

    James

    ==

    #! /usr/bin/env python

    # automagical constructor
    def construct(cls, adict):
    dflts = cls.__init__.im _func.func_defa ults
    vnames = cls.__init__.im _func.func_code .co_varnames

    argnames = vnames[1:-len(dflts)]
    argvals = [adict.pop(n) for n in argnames]

    return cls(*argvals, **adict)


    def test():

    class C(object):
    def __init__(self, arg1, arg2, kwa3=3):
    self.argsum = arg1 + arg2
    self.kwsum = kwa3
    def __str__(self):
    return "%s & %s" % (self.argsum, self.kwsum)

    # now a dict for autmagical generation
    adict = {'arg1':1, 'arg2':2, 'kwa3':42}

    print '======== test 1 ========'
    print adict
    print construct(C, adict)

    adict = {'arg1':1, 'arg2':2}
    print
    print '======== test 2 ========'
    print adict
    print construct(C, adict)

    if __name__ == "__main__":
    test()
  • George Sakkis

    #2
    Re: How much introspection is implementation dependent?

    On Feb 2, 6:56 pm, James Stroud <jstr...@mbi.uc la.eduwrote:
    Hello,
    >
    I wanted to automagically generate an instance of a class from a
    dictionary--which might be generated from yaml or json. I came up with this:
    >
    (snip)
    >
    ==
    >
    #! /usr/bin/env python
    >
    # automagical constructor
    def construct(cls, adict):
    dflts = cls.__init__.im _func.func_defa ults
    vnames = cls.__init__.im _func.func_code .co_varnames
    >
    argnames = vnames[1:-len(dflts)]
    argvals = [adict.pop(n) for n in argnames]
    >
    return cls(*argvals, **adict)
    >
    def test():
    >
    class C(object):
    def __init__(self, arg1, arg2, kwa3=3):
    self.argsum = arg1 + arg2
    self.kwsum = kwa3
    def __str__(self):
    return "%s & %s" % (self.argsum, self.kwsum)
    >
    # now a dict for autmagical generation
    adict = {'arg1':1, 'arg2':2, 'kwa3':42}
    >
    print '======== test 1 ========'
    print adict
    print construct(C, adict)
    >
    adict = {'arg1':1, 'arg2':2}
    print
    print '======== test 2 ========'
    print adict
    print construct(C, adict)
    >
    if __name__ == "__main__":
    test()
    What's the point of this ? You can call C simply by C(**adict). Am I
    missing something ?

    George

    Comment

    • James Stroud

      #3
      Re: How much introspection is implementation dependent?

      George Sakkis wrote:
      On Feb 2, 6:56 pm, James Stroud <jstr...@mbi.uc la.eduwrote:
      >
      >Hello,
      >>
      >I wanted to automagically generate an instance of a class from a
      >dictionary--which might be generated from yaml or json. I came up with this:
      >>
      >(snip)
      >>
      >==
      >>
      >#! /usr/bin/env python
      >>
      ># automagical constructor
      >def construct(cls, adict):
      > dflts = cls.__init__.im _func.func_defa ults
      > vnames = cls.__init__.im _func.func_code .co_varnames
      >>
      > argnames = vnames[1:-len(dflts)]
      > argvals = [adict.pop(n) for n in argnames]
      >>
      > return cls(*argvals, **adict)
      >>
      >def test():
      >>
      > class C(object):
      > def __init__(self, arg1, arg2, kwa3=3):
      > self.argsum = arg1 + arg2
      > self.kwsum = kwa3
      > def __str__(self):
      > return "%s & %s" % (self.argsum, self.kwsum)
      >>
      > # now a dict for autmagical generation
      > adict = {'arg1':1, 'arg2':2, 'kwa3':42}
      >>
      > print '======== test 1 ========'
      > print adict
      > print construct(C, adict)
      >>
      > adict = {'arg1':1, 'arg2':2}
      > print
      > print '======== test 2 ========'
      > print adict
      > print construct(C, adict)
      >>
      >if __name__ == "__main__":
      > test()
      >
      What's the point of this ? You can call C simply by C(**adict). Am I
      missing something ?
      >
      George
      >
      Maybe there is something wrong with my python.

      pyclass C:
      .... def __init__(a, b, c=4):
      .... print a,b,c
      ....
      pyC(**{'a':10, 'b':5, 'c':4})
      Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      TypeError: __init__() got multiple values for keyword argument 'a'


      James

      Comment

      • James Stroud

        #4
        Re: How much introspection is implementation dependent?

        George Sakkis wrote:
        On Feb 2, 6:56 pm, James Stroud <jstr...@mbi.uc la.eduwrote:
        >
        >Hello,
        >>
        >I wanted to automagically generate an instance of a class from a
        >dictionary--which might be generated from yaml or json. I came up with this:
        >>
        >(snip)
        >>
        >==
        >>
        >#! /usr/bin/env python
        >>
        ># automagical constructor
        >def construct(cls, adict):
        > dflts = cls.__init__.im _func.func_defa ults
        > vnames = cls.__init__.im _func.func_code .co_varnames
        >>
        > argnames = vnames[1:-len(dflts)]
        > argvals = [adict.pop(n) for n in argnames]
        >>
        > return cls(*argvals, **adict)
        >>
        >def test():
        >>
        > class C(object):
        > def __init__(self, arg1, arg2, kwa3=3):
        > self.argsum = arg1 + arg2
        > self.kwsum = kwa3
        > def __str__(self):
        > return "%s & %s" % (self.argsum, self.kwsum)
        >>
        > # now a dict for autmagical generation
        > adict = {'arg1':1, 'arg2':2, 'kwa3':42}
        >>
        > print '======== test 1 ========'
        > print adict
        > print construct(C, adict)
        >>
        > adict = {'arg1':1, 'arg2':2}
        > print
        > print '======== test 2 ========'
        > print adict
        > print construct(C, adict)
        >>
        >if __name__ == "__main__":
        > test()
        >
        What's the point of this ? You can call C simply by C(**adict). Am I
        missing something ?
        >
        George
        >
        Never mind. You're right.

        pyclass C(object):
        .... def __init__(self, a, b, c=4):
        .... print a,b,c
        ....
        pyC(**adict)
        10 5 4
        <__main__.C object at 0x762530>


        I guess I thought that, were it this easy, it would have been done in pyaml.

        James

        Comment

        Working...