Re:Metaclasses in Python
by gecko on Thursday December 15, 2011 @01:01PM
(#3357166)
That's not quite right. While you're correct that lambda statements are restricted, I have never actually seen a lambda expression used to extend an object. Instead, you use a named function, which has none of these restrictions:
This is, in fact, one of the reasons why the self parameter is explicit.
[ Parent
| on HN ]
The above doesn't really work as the builtin object class doesn't allow extra attributes. Still any pure Python class does by default:
class Foo(object):
pass
foo = Foo()
foo.name = ...
def hello(self):
...
foo.hello = helloYou should either remove `self` or bind it differently:
foo = Foo()
def hello():
print("hello, %s" % (foo,))
foo.hello = hello
`foo` is an instance therefore `self == foo` already. def hello(self):
print("hello, %s" % (self,))
foo.hello = types.MethodType(hello, foo)Also, i forgot to add, your code snippet doesn't work. Some magic goes into the self binding.
In [21]: def hello(self):
....: print self.name
....:
In [22]: class Foo(object):
....: name = 'blah'
....:
In [23]: goo = Foo()
go
In [24]: goo.hi = hello
In [25]: goo.hi
Out[25]: <function hello at 0x103985aa0>
In [26]: goo.hi()
TypeError Traceback (most recent call last)
TypeError: hello() takes exactly 1 argument (0 given)Use types.MethodType for that:
>>> import types
>>>
>>> def hello(self):
... print self.name
...
>>> class Foo(object):
... name = 'blah'
...
>>> goo = Foo()
>>> goo.hi = types.MethodType(hello, Foo)
>>>
>>> goo.hi()
blah
Edit: pre-2.6 you'd use "new.instancemethod()"Yes, or alternatively I believe
In [27]: class Foo(object):
....: pass
....:
In [28]: def hello(self):
....: print self
....:
In [29]: blah = Foo()
In [30]: blah.hello = hello.__get__(blah, Foo)
In [31]: blah.hello()
<__main__.Foo object at 0x10397f650>you may not have seen it, but it does work:
n [8]: class Foo(object): ...: pass ...:
In [9]: blah = Foo()
In [10]: blah.asdf = lambda x: x
In [11]: blah.asdf(3) Out[11]: 3
In [12]: blah.asdf(5) Out[12]: 5