J
James Stroud
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_defaults
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.
<aside> I 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_defaults
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()
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_defaults
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.
<aside> I 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_defaults
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 '======== test 2 ========'
print adict
print construct(C, adict)
if __name__ == "__main__":
test()