我想在我的类中定义许多方法TestClass。我想呼唤他们的名字TestClass().method_1......TestClass().method_n
我不想间接调用它们,例如通过中间方法来TestClass().use_method('method_1', params)保持与代码其他部分的一致性。
我想动态定义我的众多方法,但我不明白为什么这个最小的示例不起作用:
class TestClass:
def __init__(self):
method_names = [
'method_1',
'method_2']
for method_name in method_names:
def _f():
print(method_name)
# set the method as attribute
# (that is OK for me that it will not be
# a bound method)
setattr(
self,
method_name,
_f)
del _f
if __name__ == '__main__':
T = TestClass()
T.method_1()
T.method_2()
print(T.method_1)
print(T.method_2)
Run Code Online (Sandbox Code Playgroud)
输出是:
function_2
function_2
<function TestClass.__init__.<locals>._f at 0x0000022ED8F46430>
<function TestClass.__init__.<locals>._f at 0x0000022EDADCE4C0>
Run Code Online (Sandbox Code Playgroud)
当我期待的时候
function_1
function_2
Run Code Online (Sandbox Code Playgroud)
我尝试在很多地方放置一些 copy.deepcopy 但它没有帮助。
尝试用一个更简单的例子来缩小范围,我再次对结果感到惊讶:
class TestClass:
def __init__(self):
variable = 1
def _f():
print(variable)
del variable
setattr(
self,
'the_method',
_f)
del _f
variable = 2
if __name__ == '__main__':
T = TestClass()
T.the_method()
Run Code Online (Sandbox Code Playgroud)
输出是2我期待的1。
关于正在发生的事情有任何提示吗?
----- 编辑以给出解决方案,感谢蒂姆·罗伯茨接受的答案(并感谢卡注意到类型(自我)而不是自我 -----
最小的例子:
class TestClass:
def __init__(self):
variable = 1
def _f(captured_variable=variable):
print(captured_variable)
print(variable)
del variable
setattr(
type(self),
'the_method',
_f)
del _f
variable = 2
if __name__ == '__main__':
T = TestClass()
T.the_method()
Run Code Online (Sandbox Code Playgroud)
输出是:
1
2
Run Code Online (Sandbox Code Playgroud)
关于动态定义方法的原始问题:
class TestClass:
def __init__(self):
method_names = [
'method_1',
'method_2']
for method_name in method_names:
def _f(captured_method=method_name):
print(captured_method)
print(method_name)
# set the method as attribute
setattr(
type(self),
method_name,
_f)
del _f
if __name__ == '__main__':
T = TestClass()
T.method_1()
T.method_2()
print(T.method_1)
print(T.method_2)
Run Code Online (Sandbox Code Playgroud)
输出是:
method_1
method_2
method_2
method_2
<function TestClass.__init__.<locals>._f at 0x000001D1CF9D6430>
<function TestClass.__init__.<locals>._f at 0x000001D1D187E4C0>
Run Code Online (Sandbox Code Playgroud)
这是 Python 的经典错误之一。您获得变量的值,变量最终得到最终值。
您可以通过“捕获”变量的值作为默认值来执行您想要的操作:
for method_name in method_names:
def _f(method=method_name):
print(method)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
786 次 |
| 最近记录: |