[英]Using a base class function that takes parameters as a decorator for derived class function
[英]Access derived class attribute in base class function decorator
我想做類似的事情:
class A(Resource):
@dec(from_file=A.docpath)
def get(self):
pass
class B(A):
docpath = './docs/doc_for_get_b.json'
class C(A):
docpath = './docs/doc_for_get_c.json'
def dec(*args, **kwargs):
def inner(f):
docpath = kwargs.get('from_file')
f.__kwargs__ = open(path, 'r').read()
return f
return inner
將被調用的函數是B.get
和C.get
,從不會是A.get
。
如何訪問在class B
或class C
定義的自定義屬性docpath
其傳遞給class A
中的get
函數的裝飾器?
當前解決方案:將裝飾器放在每個派生類上...
class A(Resource):
def _get(self):
pass
class B(A):
@dec(from_file='./docs/doc_for_get_b.json')
def get(self):
return self._get()
class C(A)
@dec(from_file='./docs/doc_for_get_c.json')
def get(self):
return self._get()
這是可行的,但與之前代碼中的類的單行聲明相比,這非常丑陋。
在裝飾器內部訪問類的屬性很容易:
def decorator(function):
def inner(self):
self_type = type(self)
# self_type is now the class of the instance of the method that this
# decorator is wrapping
print('The class attribute docpath is %r' % self_type.docpath)
# need to pass self through because at the point function is
# decorated it has not been bound to an instance, and so it is just a
# normal function which takes self as the first argument.
function(self)
return inner
class A:
docpath = "A's docpath"
@decorator
def a_method(self):
print('a_method')
class B(A):
docpath = "B's docpath"
a = A()
a.a_method()
b = B()
b.a_method()
總的來說,我發現使用了多層裝飾器,即裝飾器工廠函數創建了您使用過的裝飾器,例如:
def decorator_factory(**kwargs):
def decorator_function(function):
def wrapper(self):
print('Wrapping function %s with kwargs %s' % (function.__name__, kwargs))
function(self)
return wrapper
return decorator_function
class A:
@decorator_factory(a=2, b=3)
def do_something(self):
print('do_something')
a = A()
a.do_something()
在閱讀代碼時,一件很難的事情變得正確而又不容易理解,因此我傾向於使用類屬性和通用超類方法來支持許多裝飾器。
因此,在您的情況下,請勿將文件路徑作為參數傳遞給裝飾器工廠,而應將其設置為派生類的類屬性,然后在您的超類中編寫一個泛型方法,該方法從實例的類。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.