Skip to main content
 首页 » 编程设计

python之搁置的类定义

2025年05月04日30lexus

我正在使用 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)>