类的Decorator在导入时使类NoneType

时间:2018-04-12 09:36:43

标签: python class import decorator python-decorators

我试图理解为什么我的类上的装饰器修改类的方式在尝试从另一个脚本导入类时看起来像是“NoneType”。

my_class.py 我有:

my_dict = dict()

def register(cls):
    name = cls.__name__
    my_dict[name] = cls

@register  # will be commented
class MyClass:
    def my_method(self):
        print("running class method")

print("my_dict: ", my_dict)

在另一个模块 my_main.py 中,我导入了类

from my_class import MyClass

print(type(MyClass))
print(MyClass.my_method)

如果我使用$ python3 my_main.py运行它,我会得到以下输出:

my_dict:  {'MyClass': <class 'my_class.MyClass'>}
<class 'NoneType'>
Traceback (most recent call last):
  File "my_main.py", line 4, in <module>
    print(MyClass.my_method)
AttributeError: 'NoneType' object has no attribute 'my_method'

通过评论@register中的my_class.py行,my_main.py运行时没有错误和输出:

my_dict:  {}
<class 'type'>
<function MyClass.my_method at 0x7ff06f254f28>

..但显然my_dict已不再填充。有没有办法在给定装饰器中注册my_class并在另一个脚本中导入后访问该类的属性?

1 个答案:

答案 0 :(得分:0)

装饰者不过是一个正常的功能。

我不想描述如何正确地写一个装饰器。但至少,您应该让装饰者返回class

当你为函数编写装饰器时,这是类似的。装饰者至少应该返回一个函数。

例如:

def decorator(method):
    @functools.wraps(method)
    def wrapper(*args, **kwargs):
        print("Hi")
        return method(*args, **kwargs)
    return wrapper

使用此装饰器来装饰函数时,实际上是将该函数传递给装饰器:new_function = decorator(original_function)

这意味着new_functionwrapper包裹。这就是装饰工作的方式。执行修饰函数时,它实际执行wrapper

print("Hi")
return method(*args, **kwargs)  # pass all args to original function and return its return value.

在您的代码中,您的装饰者只返回None