I was playing with metaclasses in Python 3:
class M(type):
def __new__(cls, clsname, bases, attrs):
for name, attr in attrs.items():
if callable(attr):
attrs[name] = attr
return type.__new__(cls, clsname, bases, attrs)
class C(metaclass=M):
def f(self, x):
print(x)
if __name__ == '__main__':
c = C()
c.f(1)
c.f(2)
Nothing special so far, I just hook into the creation of a class, and substitute its method with... well, itself, so no wonder everything works. But with:
class M(type):
def __new__(cls, clsname, bases, attrs):
for name, func in attrs.items():
if callable(func):
attrs[name] = lambda *args, **kwds: func(*args, **kwds)
return type.__new__(cls, clsname, bases, attrs)
It sometime works, and sometimes doesn't:
user$ python test.py
1
2
user$ python test.py
Traceback (most recent call last):
File "./meta.py", line 23, in <module>
main()
File "./meta.py", line 19, in main
instance.method(1)
File "./meta.py", line 9, in <lambda>
attrs[name] = lambda *args, **kwds: func(*args, **kwds)
TypeError: 'str' object is not callable
But I just substituted its method with a lambda wrapper! What does 'str' have to do with anything? What am I doing wrong?
(Just in case it's some weird platform-dependent implementation issue, I'm using Ubuntu Server 12.04.3...)
UPDATE: fixed the name mismatch in the traceback.