我认为我的例子会让这更容易理解:
class x():
def a(self):
return "hello"
def b(self):
return self.a() + " world"
test = x()
print test.b() # prints "hello world" as expected
test.a = lambda(self): "hola"
print test.b() # throws error:
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# File "<stdin>", line 5, in b
# TypeError: <lambda>() takes exactly 1 argument (0 given)
尝试将x()。a更新到另一个函数,但是当x()。b调用它时,它似乎不会将self作为第一个参数传递。
我期待得到“hola world”。
答案 0 :(得分:1)
如果你这样做,你可以看到问题
print type(test.a) # <type 'function'>
print type(test.b) # <type 'instancemethod'>
如果您确实只想在a
上修补test
(而不是x
的所有实例),您可以执行以下操作:
import types
test.a = types.MethodType((lambda self: "hola"), test, x)
创建instancemethod
类型的对象。
答案 1 :(得分:0)
保持笔直的功能和方法可能很棘手。一个好的经验法则是,如果你需要它作为一个方法,将它存储在类中。
你什么时候需要它才是一种方法?当代码访问实例或类的部分时。
在您的简单示例中,替换代码不访问实例,因此您可以在实例上保留一个函数,如下所示:
test.a = lambda: "hola"
这是一个访问实例的示例,代码存储在类中(这是您通常需要的):
x.c = lambda self: self.b().upper()
或存储在实例中:
# using MethodType
import types
test.c = types.MethodType((lambda self: self.b().upper()), test)
# using partial
import functools
test.c = functools.partial((lambda self: self.b().upper()), test)
# just using the instance name, as Ryan did
test.c = lambda: test.some_attribute
虽然最后一种方法大部分时间都可以使用,但确实存在一个缺陷:
oops = test
del oops
oops.c()
Traceback (most recent call last):
File "test.py", line 42, in <module>
oops.c()
File "test.py", line 38, in <lambda>
test.c = lambda: test.some_attribute
NameError: global name 'test' is not defined
要记住一些事情。