假设我正在编写一个使用了许多GUI控件的应用程序,我正在编写Python代码。每个控件都由一个类描述,我想将所有这些类聚合到一个名为gui
的模块中。作为一名经验丰富的C / C ++开发人员,我最有意义的是按文件分隔类实现,如下所示:
gui/MainWindow.py
gui/Widget1.py
gui/Widget2.py
在上文中,MainWindow
类的规范将在MainWindow.py
中。但是,如果我以这种方式放置文件,那么获取这些类的语法如下:
import gui
w = gui.MainWindow.MainWindow()
这似乎是多余的。绕过此限制的一种方法是编辑gui/__init__.py
来说:
from gui.MainWindow import *
from gui.Widget1 import *
from gui.Widget2 import *
将类带入gui
模块命名空间。然后我可以按如下方式访问它们:
w = gui.MainWindow()
通常这样做吗?它是否有足够的Pythonicity被认为适合社区?我可以看到的一个缺点是,当我向gui/__init__.py
模块添加新的子模块时,我需要确保gui
。我不喜欢这样的手动步骤。
如何更好地解决这个问题的想法和/或建议会很棒。
答案 0 :(得分:2)
请勿导入*
(除非您某些不存在冲突;此规则可以针对包作者),但当然这是一个可以接受的解决方案。
答案 1 :(得分:0)
可能您之前注意过这些PEP和文档站点:
所以我唯一可以添加的就是不使用import *
。一个例子:
>>> from pylab import *
>>> any(False for i in range(5))
True
虽然你有效地争辩说你知道自己在做什么。您不能假设您的软件包中import *
的所有潜在重新用户都知道他们在他们和您的代码之间拆除最终名称空间障碍时所隐藏的内容。
这给出了令人讨厌的错误。另见:
现在当用户写
from sound.effects import *
时会发生什么?理想情况下,人们希望以某种方式传递给文件系统,找到包中存在哪些子模块,并将它们全部导入。这可能需要很长时间,导入子模块可能会产生不必要的副作用,这种副作用只有在显式导入子模块时才会发生。 Docs
和
(导入*不是一个选项;-) PEP328
和
命名空间是一个很好的主意 - 让我们做更多的事情吧! PEP20
但这些只是指导方针/建议/个人偏好,当这些不适用时肯定存在边缘情况。