访问基 class 函数装饰器中的派生 class 属性
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 ...
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()
这行得通,但与前面代码中 classes 的单行声明相比,它非常难看。
要在装饰器中访问 class 的属性很容易:
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()
阅读代码时很难正确理解,所以我会错误地使用 class 属性和通用的 superclass 方法来支持大量装饰器。
所以在你的情况下,不要将文件路径作为参数传递给装饰器工厂,而是将其设置为派生的 classes 上的 class 属性,然后编写superclass 中的一个通用方法,它从实例的 class.
中读取 class 属性
我想做类似的事情:
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 ...
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()
这行得通,但与前面代码中 classes 的单行声明相比,它非常难看。
要在装饰器中访问 class 的属性很容易:
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()
阅读代码时很难正确理解,所以我会错误地使用 class 属性和通用的 superclass 方法来支持大量装饰器。
所以在你的情况下,不要将文件路径作为参数传递给装饰器工厂,而是将其设置为派生的 classes 上的 class 属性,然后编写superclass 中的一个通用方法,它从实例的 class.
中读取 class 属性