Kur*_*eek 1 python namespaces python-import
我经常发现用小写字母命名包含类定义和该类实例的模块,并使用驼峰式命名作为类名是“自然的”。例如,我想这样做:
In [2]: from publisher import Publisher
In [3]: publisher = Publisher()
Run Code Online (Sandbox Code Playgroud)
这里我有一个名为 的模块publisher,还有一个以Publisher相同方式调用的实例。模块和实例似乎都按预期“工作”:
In [4]: from publisher import RandomData
In [5]: publisher.random.uuid()
Out[5]: 'c490508d-2071-536e-2f38-4b03b04351e1'
Run Code Online (Sandbox Code Playgroud)
我从模块导入了另一个类并调用了实例方法。Python 是否“从上下文中理解”我指的是模块还是实例?以这种方式重复使用名称可以吗?
你没有隐藏任何东西,这里没有重复使用任何名字。在您使用 . 创建该实例之前,该名称publisher不会在您的命名空间中使用publisher = Publisher()。publisher如果您尝试在该行之后使用该名称from publisher import Publisher,则会出现NameError异常。
这是因为该from <module> import <name>表单仅在您的名称空间中设置<name>。<name>从哪里进口并不重要;您永远不会<module>在您的命名空间中获得名称。
换句话说,该from publisher import Publisher声明基本上可以翻译为:
if 'publisher' not in sys.modules:
# find and load the publisher module
# sys.modules['publisher'] = newly_loaded_module
Publisher = sys.modules['publisher'].Publisher # set the Publisher global
Run Code Online (Sandbox Code Playgroud)
除了名称sys从未在命名空间中设置之外,Python 只是sys.modules直接在内部访问。
所以,从技术角度来看:不,这完全没问题。
您可能会发现,使用实例变量的模块名称可能会导致未来读者(如果不是 Python)对该名称所指代的内容产生混淆。
您可能也对此感到困惑
import publisher
publisher = publisher.Publisher()
Run Code Online (Sandbox Code Playgroud)
这可能会影响该模块。该行import publisher设置全局名称publisher,并在下一行替换 publisher为新的对象引用。
转换成同一种sys.modules语言,你会这样做:
if 'publisher' not in sys.modules:
# find and load the publisher module
# sys.modules['publisher'] = newly_loaded_module
publisher = sys.modules['publisher'] # set the publisher global
publisher = publisher.Publisher() # set the publisher global to something else
Run Code Online (Sandbox Code Playgroud)
这也很好,除非您期望publisher.Publisher()稍后会再次起作用。publisher不再引用该模块,因此可能会导致问题。这对于人类读者来说更加令人困惑。