469,578 Members | 1,933 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,578 developers. It's quick & easy.

Class factory functions

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:
>>class Parrot:
.... def __init__(self, colour): self.colour = colour
....
>>VParrot = verbosify_oclass(Parrot)
bird = VParrot('red')
Calling initializer __init__ ...
>>bird.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:
>>vint = verbosify_nclass(int)
vint(42)
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

--
Steven.

Mar 25 '07 #1
2 1526
Steven D'Aprano wrote:
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:
>>>class Parrot:
... def __init__(self, colour): self.colour = colour
...
>>>VParrot = verbosify_oclass(Parrot)
bird = VParrot('red')
Calling initializer __init__ ...
>>>bird.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:
>>>vint = verbosify_nclass(int)
vint(42)
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?
Why would you skip VClass in the super() calls? This should work:

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(VClass, cls).__new__(cls, *args, **kwargs)
def __init__(self, *args, **kwargs):
print "Calling initializer __init__ ..."
super(VClass, self).__init__(*args, **kwargs)
return VClass

Peer
Mar 25 '07 #2
On Sun, 25 Mar 2007 11:58:00 +0200, Peter Otten wrote:
>But it doesn't work:
>>>>vint = verbosify_nclass(int)
vint(42)
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?

Why would you skip VClass in the super() calls?

That's a good question. If I every get a good answer, I'll let you know.
This should work:
[snip]

As indeed it seems like it does.

Thank you,

--
Steven.

Mar 25 '07 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

39 posts views Thread by Marco Aschwanden | last post: by
17 posts views Thread by Aguilar, James | last post: by
reply views Thread by Hatim Ali | last post: by
11 posts views Thread by Manuel | last post: by
16 posts views Thread by Manuel | last post: by
6 posts views Thread by GroupReader | last post: by
11 posts views Thread by digz | last post: by
4 posts views Thread by =?Utf-8?B?SmVzc2ljYQ==?= | last post: by
44 posts views Thread by Steven D'Aprano | last post: by
4 posts views Thread by guiromero | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.