[英]Python - Pass class as argument to decorator of method within that class?
我正在尋找執行以下操作:
class A(object):
def first_method(self):
print "I'm the first method!"
@some_decorator(A.first_method)
def second_method(self):
print "I'm the second method!"
但是我遇到了在解析裝飾器時A
本身未定義的問題。 有什么辦法可以讓我在裝飾器中引用A
嗎? 或者,如果我只是通過裝飾器綁定方法first_method
是否可以恢復first_method
屬於A
?
在 python 3 中,你可以只說@some_decorator(first_method)
,它會起作用,因為所有方法都是作為容器的類中的普通函數。
在python 2中,有一個復雜的綁定和未綁定、實例、類和靜態方法系統。 因此,您無法在類定義中訪問first_method
(直到類完全形成)。
一個小的解決方法是將該類拆分為兩個類:
class BaseA(object):
def first_method(self):
print "I'm the first method!"
class A(BaseA):
@some_decorator(BaseA.first_method)
def second_method(self):
print "I'm the second method!"
不是所有情況的最佳解決方案,但會起作用。
另外,請記住,在這兩種情況下(py2 和 py3),裝飾器將引用此處聲明的first_method
。 如果任何后代類重新定義了該方法,則裝飾器中將不會使用新方法; 只有父級會被使用。
可能,您根本不應該引用first_method
。 相反,只需在裝飾器的包裝器中接受self
/ cls
第一個位置參數,並在那里使用self.first_method
/ cls.first_method
:
import functools
def some_decorator(fn):
@functools.wraps(fn)
def wrapper(self, *args, **kwargs):
first_method = self.first_method
first_method()
return fn(self, *args, **kwargs)
return wrapper
class A(object):
def first_method(self):
print "I'm the first method of A!"
@some_decorator
def second_method(self):
print "I'm the second method!"
class B(A):
def first_method(self):
print "I'm the first method of B!"
A().second_method()
# I'm the first method of A!
# I'm the second method!
B().second_method()
# I'm the first method of B!
# I'm the second method!
如果要使該方法可配置:
def some_decorator(method_name):
def decorator(fn):
@functools.wraps(fn)
def wrapper(self, *args, **kwargs):
first_method = getattr(self, method_name)
first_method()
return fn(self, *args, **kwargs)
return wrapper
return decorator
class A(object):
def first_method(self):
print "I'm the first method of A!"
@some_decorator('first_method')
def second_method(self):
print "I'm the second method!"
class B(A):
def first_method(self):
print "I'm the first method of B!"
您可以將裝飾器用作經典函數(不帶 @):
def some_decorator(arg):
# ...
pass
class A(object):
def first_method(self):
print("I'm the first method!")
def second_method(self):
print("I'm the second method!")
A.second_method = some_decorator(A.first_method)(A.second_method)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.