首页 > 解决方案 > 函数返回后,函数创建的类的虚拟名称似乎仍然存在 -python

问题描述

假设我Hello用一个调用Hello. 如果我将类分配给Hello2and del Hello,那么该方法将引发一个异常,指示它找不到 name Hello

另一方面,假设我运行一个函数,该函数dummyName使用一个方法创建一个类,该方法调用dummyName并将返回的类分配给Bye. 如果我将类分配给Bye2and del Bye,那么该方法仍然运行。看起来好像变量dummyName仍然存在。如果是,它的命名空间在哪里,它是如何决定在函数返回后哪种类型的对象保留一个神秘的引用?

编辑:评论者建议该类由闭包引用。事实上,一个 FUNCTION 有一个__closure__属性,如果该函数嵌套在另一个函数中,则该__closure__属性引用一个对象元组cell,每个对象都有一个cell_contents引用在外部函数中创建的对象的属性。但是,该类Bye2没有__closure__属性,所以问题仍然存在。

def make_Bye():
    class dummyName:
        word = 'bye'
        def talk(self):
            return dummyName.word
    return dummyName

Bye = make_Bye()

class Hello:
    word = 'hello'
    def talk(self):
        return Hello.word

print('1.', Bye.talk(None)) # 1. bye
print('2.', Hello.talk(None)) # 2. hello

# now let's give these classes new names and delete the old names
Hello2 = Hello
del Hello
Bye2 = Bye
del Bye

print('3.', Bye2.talk(None)) # 3. bye
print('4.', Hello2.talk(None)) # NameError: name 'Hello' is not defined

标签: pythonpython-3.xnamespaces

解决方案


看起来好像变量 dummyName 仍然存在。

你是对的。

如果是,它的命名空间在哪里

dummyName不再可以直接访问:它.make_Bye

Bye2.__qualname__
# => make_Bye.<locals>.dummyName`

另一方面Hello2是:

Hello2.__qualname__
# => Hello

再也找不到了。

编辑:这是不正确的;它不在关闭中。正如我在评论中所说,闭包是一种允许函数访问其外部变量的机制;这里从函数中导出了一个值。说实话,我对Bye2有效的事实并不感到惊讶,而不是对无效的事实感到惊讶Hello2


推荐阅读