簡體   English   中英

訪問基類函數裝飾器中的派生類屬性

[英]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.getC.get ,從不會是A.get

如何訪問在class Bclass 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM