将实例命名为模块是否可以?

时间:2016-11-10 12:32:45

标签: python namespaces python-import

我经常发现它很自然'将包含类定义的模块和该类的实例命名为小写,并使用camel-case作为类名。例如,我想这样做:

In [2]: from publisher import Publisher

In [3]: publisher = Publisher()

这里我有一个名为publisher的模块,但也有Publisher的实例以相同的方式调用。看起来模块和实例都可以正常工作。正如所料:

In [4]: from publisher import RandomData

In [5]: publisher.random.uuid()
Out[5]: 'c490508d-2071-536e-2f38-4b03b04351e1'

我从模块中导入了另一个类并调用了一个实例方法。 Python'是否从上下文中理解'我是指模块还是实例?以这种方式重用名称是否可以?

1 个答案:

答案 0 :(得分:4)

你没有任何影子,这里没有重复使用名字。在您使用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

除了名称sys从未在命名空间中设置外,Python只是直接在内部访问sys.modules

所以,从技术角度来看:不,这完全没问题。

可能发现使用实例变量的模块名称可能会对名称引用代码的未来读者造成混淆,如果不是蟒。

您可能也与

混淆了
import publisher
publisher = publisher.Publisher()

那可能会 影子模块。第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

那也很好,除非你希望publisher.Publisher()稍后会再次使用。 publisher不再引用该模块,因此可能会导致问题。这对人类读者来说更加困惑。