Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 访问基类函数装饰器中的派生类属性_Python_Introspection_Python Decorators - Fatal编程技术网

Python 访问基类函数装饰器中的派生类属性

Python 访问基类函数装饰器中的派生类属性,python,introspection,python-decorators,Python,Introspection,Python Decorators,我想做一些类似的事情: 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): docpat

我想做一些类似的事情:

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()
这是一件很难正确理解的事情,在阅读代码时也不容易理解,因此我倾向于使用类属性和泛型超类方法,而倾向于使用大量的装饰器


因此,在您的情况下,不要将文件路径作为参数传递给装饰器工厂,而是将其设置为派生类的类属性,然后在超类中编写一个泛型方法,从实例的类中读取类属性。

以及其他几件事,现在还不清楚装饰者对
f.\uuuuuKwargs\uuuuuuuuuuuu
的赋值完成了什么——因为
\uuuuuuKwargs\uuuuuuuuuuuuu
在Python中不是一个标准的特殊属性(而且你不应该使用该模式来发明自己的)。谢谢你,这正是我想要的。荣誉