【问题标题】:NameError with super() inside decorator装饰器内部带有 super() 的 NameError
【发布时间】:2017-10-30 04:42:51
【问题描述】:

使用python 2.7

我正在使用装饰器在导入时创建一个对象库,并在导入时对每个对象的实例进行一些检查;主要是重复检查...

我最近切换到使用 super() 以利用其多重继承处理,但它会在实例化的对象上引发 NameError

简化代码高亮问题:

class Lib(object):
    def __init__(self):
        print "library created"
        self.lib = {}

    def add_obj(self, obj):
        print "object being added to library --> %s" % obj.__name__
        inst = obj()
        print inst.name
        self.lib[obj.__name__] = obj

def Reg(obj):
    global test_lib
    test_lib.add_obj(obj)

test_lib = Lib()

@Reg
class A(object):
    def __init__(self):
        object.__init__(self)
        self.name = "A instance"

@Reg
class B(object):
    def __init__(self):
        super(B, self).__init__()
        self.name = "B instance"

输出

>>> from testing import *
library created
object being added to library --> A
A instance
object being added to library --> B
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "testing.py", line 25, in <module>
    class B(object):
  File "testing.py", line 14, in Reg
    test_lib.add_obj(obj)
  File "testing.py", line 8, in add_obj
    inst = obj()
  File "testing.py", line 27, in __init__
    super(B, self).__init__()
NameError: global name 'B' is not defined

似乎存在范围问题?排除装饰器,B 类实例化没有问题。

有什么建议吗?

【问题讨论】:

    标签: python python-2.7 super python-decorators


    【解决方案1】:

    您正试图在 B 完成定义之前对其进行实例化。

    修复它:

    Lib.add_obj()中删除这些行:

    inst = obj()
    print inst.name
    

    为什么?

    装饰器Reg参与了B的定义。因此,在退出 Reg 之前,您将无法通过该名称实例化 B

    【讨论】:

    • 您好,斯蒂芬,感谢您的回复。我在 Lib.add_obj() 内部进行实例化,因为我想对实例进行一些错误检查,所以它在那里是为了达到目的。您能否详细说明“Reg 参与 B 的定义”。为什么 Reg 不会以同样的方式影响 A 的定义?
    • 如果你想在 super 中使用名称B,你不能这样做,因为在装饰器退出之前B 不存在。
    猜你喜欢
    • 2012-03-15
    • 2014-07-21
    • 2016-09-02
    • 2020-05-02
    • 2012-12-23
    • 2014-02-16
    • 2013-01-20
    • 2014-05-19
    • 2012-01-28
    相关资源
    最近更新 更多