Python 3 Super And Metaprogramming
Solution 1:
Note: I corrected the spelling of Original
in this answer
It appears that the problem is that when your Modified
object is being instantiated and super
is called, its being called like: super(Original, self)
since those are the default arguments for super
. Since Original
is not a superclass of Modified
(check isinstance(m, Original)
), python is not allowing you to call super
in that way.
The following code does something similar to yours but better illustrates the problem.
classBase():def__init__(self):
print("Base init")
classOriginal(Base):def__init__(self):
super().__init__()
print("Orginal init")
classModified(Base):def__init__(self):
super(Original, self).__init__() # illegal
Modified.__name__ == Original.__name__
m = Modified() # raises same Exception that your your code does
Adding Original
to the bases
of Modified
will make it work:
Modified = type(Original.__name__, (Original,) + Original.__bases__, dict(Original.__dict__))
Edit:
Per the comments, the above suggestion can be simplified since all the methods contained within Original
will be included in Modified
without needing to pass the dict
in the type
call:
Modified = type(Original.__name__, (Original,), {})
and going one step further, if you don't want Modified
to be a subclass of Original
, you could simply make Modified
a copy of Original
and then add attributes the same as you do in your example:
from copy import deepcopy
Modified = deepcopy(Original)
Modified.f = lambda self: print("f")
m = Modified()
Looking at this answer, it appears that you cannot use deepcopy
to copy classes, and given that you have that super()
call in your Original.__init__
method, Modified
be a subclass of Original
(unless you also modify the __init__
method in your Modified
class after it's been "copied").
Solution 2:
According to the documentation,
Also note that, aside from the zero argument form, super() is not limited to use inside methods. The two argument form specifies the arguments exactly and makes the appropriate references. The zero argument form only works inside a class definition, as the compiler fills in the necessary details to correctly retrieve the class being defined, as well as accessing the current instance for ordinary methods.
So, the super()
in the code is equivalent to super(Orginal, self).__init__()
, and it's determined in compile time.
Post a Comment for "Python 3 Super And Metaprogramming"