Reputation: 3494
Update: made some progress and simplified the example, although I'm currently stumped by the latest error. I have no idea why the super().__init__
method is unbound.
import types
class VeryImportantSuperClass(object):
def __init__(self, anArg, anotherArg):
self.anArg = anArg
#Extremely clever code here
def createSubclassAttempt1(name):
source = 'def __init__(self, arg):\n' +\
' super(' + name + ', self).__init__(arg, 6.02e23)\n' +\
' self.foo = self.anArg + 3\n'
cls = type(name, (VeryImportantSuperClass,), {})
d = {name: cls}
exec source in d
cls.__init__ = types.MethodType(d['__init__'], cls)
return cls
if __name__ == '__main__':
cls = createSubclassAttempt1('Foo')
cls('foo')
output:
Traceback (most recent call last):
File "/home/newb/eclipseWorkspace/TestArea/subclassWithType.py", line 27, in <module>
cls('foo')
File "<string>", line 2, in __init__
TypeError: unbound method __init__() must be called with Foo instance as first argument (got str instance instead)
There's got to be some way to call a superclass method from a subclass created by type, but I'm dashed if I can see how.
Upvotes: 1
Views: 113
Reputation: 123463
This seems to work and do what you want. Theself.foo = self.anArg + 3
statement had to be changed toself.foo = self.anArg + "3"
to avoid aTypeError
when attempting to concatenate astr
and anint
objects which is what happens with acls('f00')
call as shown in the code in your question.
import types
class VeryImportantSuperClass(object):
def __init__(self, anArg, anotherArg):
self.anArg = anArg
#Extremely clever code here
def createSubclassAttempt1(name):
source = ('def __init__(self, arg):\n'
' super(' + name + ', self).__init__(arg, 6.02e23)\n'
' self.foo = self.anArg + "3"\n')
d = {}
exec(source, d)
cls = type(name, (VeryImportantSuperClass,), d)
d[name] = cls
return cls
if __name__ == '__main__':
cls = createSubclassAttempt1('Foo')
inst = cls('foo')
print(cls('foo').foo) # prints "foo3"
(Works in both Python 2.7.3 & 3.3)
Upvotes: 1
Reputation: 86502
Use a closure for __init__
in the function creating the class:
class VeryImportantSuperClass(object):
def __init__(self, anArg, anotherArg):
self.anArg = anArg
def CreateSubclass(name):
def sub__init__(self, arg):
super(klass, self).__init__(arg, 6.02e23)
self.foo = self.anArg + 3
klass = type(name, (VeryImportantSuperClass, ),
{'__init__': sub__init__})
return klass
if __name__ == '__main__':
cls = CreateSubclass('Foo')
print(cls(3).foo)
Upvotes: 4