staticmethod vs metaclass

R

Robin Becker

A colleague wanted to initialize his class __new__ and tried code resembling this

#######################1
class Metaclass (type):
def __init__(cls, name, bases, *args, **kwargs):
super(Metaclass, cls).__init__(cls, name, bases, *args, **kwargs)
print 'cls=',cls, cls.__new
cls.__new__ = staticmethod(cls.__new)

def __new(self,cls,*args):
print 'new(',self,cls,args,')'
return object.__new__(cls,*args)

class A:
__metaclass__ = Metaclass
def __init__(cls,*args):
print '__init__(',cls,args,')'
A(3,4,5)
#######################
cls= <class '__main__.A'> <bound method Metaclass.__new of <class '__main__.A'>>
new( <class '__main__.A'> <class '__main__.A'> (3, 4, 5) )
__init__( <__main__.A object at 0x008D0AB0> (3, 4, 5) )
#######################

We wanted to eliminate the extra self argument in the constructed class __new__
so tried
#######################2
class Metaclass (type):
def __init__(cls, name, bases, *args, **kwargs):
super(Metaclass, cls).__init__(cls, name, bases, *args, **kwargs)
print 'cls=',cls, cls.__new
cls.__new__ = staticmethod(staticmethod(cls.__new))

def __new(cls,*args):
print 'new(',cls,args,')'
return object.__new__(cls,*args)

class A:
__metaclass__ = Metaclass
def __init__(cls,*args):
print '__init__(',cls,args,')'
A(3,4,5)
#######################
cls= <class '__main__.A'> <bound method Metaclass.__new of <class '__main__.A'>>
Traceback (most recent call last):
File "mmm.py", line 15, in ?
A(3,4,5)
TypeError: 'staticmethod' object is not callable
#######################

A bit puzzling, but after thought we found both the following do what we want
with the __new__ argument signature.
#######################3
class Metaclass (type):
def __init__(cls, name, bases, *args, **kwargs):
super(Metaclass, cls).__init__(cls, name, bases, *args, **kwargs)
print 'cls=',cls, cls.__new
cls.__new__ = staticmethod(cls.__new)

def __new(cls,*args):
print 'new(',cls,args,')'
return object.__new__(cls,*args)
__new = staticmethod(__new)

class A:
__metaclass__ = Metaclass
def __init__(cls,*args):
print '__init__(',cls,args,')'
A(3,4,5)
#######################
cls= <class '__main__.A'> <function __new at 0x008D60F0>
new( <class '__main__.A'> (3, 4, 5) )
__init__( <__main__.A object at 0x008D0C10> (3, 4, 5) )
#######################

#######################4
class Metaclass (type):
def __init__(cls, name, bases, *args, **kwargs):
super(Metaclass, cls).__init__(cls, name, bases, *args, **kwargs)
print 'cls=',cls, cls.__new
cls.__new__ = cls.__new

def __new(cls,*args):
print 'new(',cls,args,')'
return object.__new__(cls,*args)
__new = staticmethod(staticmethod(__new))

class A:
__metaclass__ = Metaclass
def __init__(cls,*args):
print '__init__(',cls,args,')'

A(3,4,5)
#######################
cls= <class '__main__.A'> <staticmethod object at 0x008D0B90>
new( <class '__main__.A'> (3, 4, 5) )
__init__( <__main__.A object at 0x008D0D90> (3, 4, 5) )
#######################

This does what we want in terms of the signature, but we aren't calling the
correct super __new__, any ideas how we can do that?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top