S
Steven D'Aprano
Here's a simple class-factory function that returns a sub-class of the
old-style class it is passed.
def verbosify_oclass(klass):
"""Returns a verbose sub-class of old-style klass."""
class VClass(klass):
def __init__(self, *args, **kwargs):
print "Calling initializer __init__ ..."
klass.__init__(self, *args, **kwargs)
return VClass
Here it is in action:
.... def __init__(self, colour): self.colour = colour
....'red'
Here's an equivalent for new-style classes. It uses super() because I
understand that super() is preferred to calling the super-class by name.
def verbosify_nclass(klass):
"""Returns a verbose sub-class of new-style klass."""
class VClass(klass):
def __new__(cls, *args, **kwargs):
print "Calling constructor __new__ ..."
return super(klass, cls).__new__(cls, *args, **kwargs)
def __init__(self, *args, **kwargs):
print "Calling initializer __init__ ..."
super(klass, self).__init__(*args, **kwargs)
return VClass
But it doesn't work:
Calling constructor __new__ ...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in __new__
TypeError: object.__new__(VClass) is not safe, use int.__new__()
What am I doing wrong?
Here's one solution: dump the call to super() and call the super-class
directly. It seems to work. Are there any problems in not using super()?
What about multiple inheritance?
def verbosify_nclass2(klass):
"""Returns a verbose sub-class of new-style klass."""
class VClass(klass):
def __new__(cls, *args, **kwargs):
print "Calling constructor __new__ ..."
return klass.__new__(klass, *args, **kwargs)
def __init__(self, *args, **kwargs):
print "Calling initializer __init__ ..."
super(klass, self).__init__(*args, **kwargs)
return VClass
old-style class it is passed.
def verbosify_oclass(klass):
"""Returns a verbose sub-class of old-style klass."""
class VClass(klass):
def __init__(self, *args, **kwargs):
print "Calling initializer __init__ ..."
klass.__init__(self, *args, **kwargs)
return VClass
Here it is in action:
.... def __init__(self, colour): self.colour = colour
....'red'
Here's an equivalent for new-style classes. It uses super() because I
understand that super() is preferred to calling the super-class by name.
def verbosify_nclass(klass):
"""Returns a verbose sub-class of new-style klass."""
class VClass(klass):
def __new__(cls, *args, **kwargs):
print "Calling constructor __new__ ..."
return super(klass, cls).__new__(cls, *args, **kwargs)
def __init__(self, *args, **kwargs):
print "Calling initializer __init__ ..."
super(klass, self).__init__(*args, **kwargs)
return VClass
But it doesn't work:
Calling constructor __new__ ...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in __new__
TypeError: object.__new__(VClass) is not safe, use int.__new__()
What am I doing wrong?
Here's one solution: dump the call to super() and call the super-class
directly. It seems to work. Are there any problems in not using super()?
What about multiple inheritance?
def verbosify_nclass2(klass):
"""Returns a verbose sub-class of new-style klass."""
class VClass(klass):
def __new__(cls, *args, **kwargs):
print "Calling constructor __new__ ..."
return klass.__new__(klass, *args, **kwargs)
def __init__(self, *args, **kwargs):
print "Calling initializer __init__ ..."
super(klass, self).__init__(*args, **kwargs)
return VClass