![](/img/trans.png)
[英]How to define method to act as decorator for other methods inside the same class in Python?
[英]How to define methods dynamically inside a python class?
我想在我的类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)
输出是:
function_2
function_2
<function TestClass.__init__.<locals>._f at 0x0000022ED8F46430>
<function TestClass.__init__.<locals>._f at 0x0000022EDADCE4C0>
当我期待的时候
function_1
function_2
我试图在很多地方放一些 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()
输出是2
而我期待1
。
关于发生了什么的任何提示?
最小的例子:
class TestClass:
def __init__(self):
variable = 1
def _f(captured_variable=variable):
print(captured_variable)
print(variable)
del variable
setattr(
self,
'the_method',
_f)
del _f
variable = 2
if __name__ == '__main__':
T = TestClass()
T.the_method()
输出是:
1
2
关于动态定义方法的原始问题:
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(
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)
输出是:
method_1
method_2
method_2
method_2
<function TestClass.__init__.<locals>._f at 0x000001D1CF9D6430>
<function TestClass.__init__.<locals>._f at 0x000001D1D187E4C0>
这是典型的 Python 绊脚石之一。 你得到变量的值,变量以最终值结束。
您可以通过“捕获”变量的值作为默认值来执行您想要的操作:
for method_name in method_names:
def _f(method=method_name):
print(method)
为了更清楚地说明如何解决范围问题,您可以将该方法作为 lambda 函数的关键参数直接传递,一种可能性是:
class TestClass:
def __init__(self, *methods):
self.methods = methods
def add_methods(self):
for method in self.methods:
setattr(type(self), method.__name__, lambda self, m=method: m())
def method_1(): return '1'
def method_2(): return '2'
t = TestClass(method_1, method_2)
t.add_methods()
print(t.method_1())
print(t.method_2())
输出
1
2
我修改了一些原始代码,但请注意setattr(type(self), ...)
!!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.