![](/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.