在类定义的装饰器上无法调用NoneType对象

时间:2020-10-19 22:43:11

标签: python python-3.x python-decorators nonetype

我有一个奇怪的特定问题,与SE上常见的总体NoneType对象问题有关。我尝试使用修饰器功能打开文件,而修饰的功能将应用特定于文件类型的特定操作(aka文本,RTF,PDF等)

该过程可以很好地解析,并且可以通过对象创建和类初始化进行工作,但是当我尝试调用PDFReader函数时会引发异常,该函数目前仅具有"Reached"的调试打印语句。

我发现这是由于我使用的双重定义方法所致,因为函数调用似乎在父函数中,而我尝试访问的实际参数只能在子函数中使用。

我的问题是:如果我希望有一个通过self使用对象的初始化变量的类绑定装饰器,如何修复我的代码,或者有更好的方法来实现我正在尝试的东西?

Filehandler.py:

class Fileloader(object):

    class _decorators():
        @classmethod
        def _reader(cls, decorated):
            print('File opened in Read-Only Mode')
             #---No error if "decorated()" called here.

            def decorator(self, *args, **kwargs):
                print(self._file) #---Prints to console then throws the exception
                decorated(self, *args, **kwargs)
                ...


    def __init__(self, filename, mode='rb'):
        self._file = filename
        self._mode = mode
        print(self._file)

    @_decorators._reader
    def pdfReader(self):
        print("reached") #---never reached
        ...


Test = Fileloader('test.pdf')
Test.pdfReader()

1 个答案:

答案 0 :(得分:0)

超级容易修复,我只是盯着代码看了很久。

感谢@martineau指出我的外部装饰器不返回任何内容。

固定代码不变

class Fileloader(object):
    class _decorators():
        @classmethod
        def _reader(cls, decorated):
            print('File opened in Read-Only Mode')

            def decorator(self, *args, **kwargs):
                print(self._file)
                with open(self._file, mode=self._mode) as self.f:
                    print('Decorator')
                    decorated(self, *args, **kwargs)
                    pass

            return decorator #<----- Added this and it works as it should

edit:对于我之后的那些需要解释发生的事情的人,我制作了一个内部类class _decorators()来允许使用嵌套函数(@classmethod def_reader(cls, decorated),该函数采用{ {1}}(类的缩写)和cls(这是我用于传递函数的关键字),然后定义一个内部函数,以便我可以访问该对象的decorated字典,这是由于Python的工作原理而完成的。

Python将首先解析部分代码,因此,如果我只有内部函数self,则它将传递异常,因为此时没有decorator属性。

它通过self初始化对象之后,它确实具有一个Test = Fileloader('test.pdf')属性,可以在运行时由内部函数self访问。因此,对嵌套函数的解析器需求将在解析时由内部函数传递,但在实例化对象时将在运行时返回并读取它。