我正在使用 python 3.5。对 python 相当陌生,但对编程并不陌生。我有如下三个源文件(我实际所做的一个大大简化的版本):
c.py
class C:
def __init__(self, x):
self.x = x
def method(self):
print(self.x)
初始化文件
import shelve
from c import C
db = shelve.open("DB")
db['key1'] = C("test")
db.close()
测试.py
import shelve
db = shelve.open("DB")
obj = db['key1']
obj.method() # this works
C.method(obj) # this doesn't -- 'C' not defined
db.close()
所以我运行 init.py 来设置我的搁置数据库。然后我运行 test.py。它很高兴执行 obj.method(),所以它似乎知道类 C,即使我没有明确导入它(Lutz 说它存储在数据库中)。但是如果我尝试做 C.method(obj) (并不是说我一定需要这样调用它,而是将 C 用作类(例如创建新对象)有它的用处)它说 'C' 是没有定义的。但是,如果我将“from c import C”添加到 test.py,那么它就可以工作了。所以在某种程度上它似乎知道 C 的定义,但它又不知道。我很想知道这是为什么。
请您参考如下方法:
当 shelve 序列化一个对象时(我相信是通过酸洗它),它会存储类的导入路径以供以后取消酸洗。当它检索对象时,pickle 导入模块 (c) 并将 C 的实例返回给您(相当于最初是连载的)。
到目前为止,根据您的观察,这对您来说并不是什么新鲜事。但是,当它导入 c 时,它不会将其导入到您当前的 namespace 中。事实上,它将它导入到 very localized namespace 中。 .因此,虽然 c 模块已被导入(您可以在 sys.modules 中找到它),但您不会找到 c 或 C 在您当前的命名空间中,因为您还没有将它导入那里。
换句话说,简单地导入某些东西并不能使程序中的每个 模块都可以访问它。它仅使导入它的模块(实际上是作用域)可以访问它。我可以导入 os ,但仅仅因为 os 导入 sys 并不意味着我可以立即访问 sys。在开始使用之前,我也需要导入它。
>>> import os
>>> sys
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'sys' is not defined
>>> os.sys
<module 'sys' (built-in)>
>>> import sys
>>> sys
<module 'sys' (built-in)>
