简体   繁体   English

这是构建模块的Pythonic方式吗?

[英]Is this a Pythonic way of structuring modules?

Suppose that I was writing an application that used a number of GUI controls that I'm writing Python code for. 假设我正在编写一个使用了许多GUI控件的应用程序,我正在编写Python代码。 Each control is described by a class, and I want to aggregate all of those classes into a module, called gui . 每个控件都由一个类描述,我想将所有这些类聚合到一个名为gui的模块中。 As a seasoned C/C++ developer, it makes most sense to me to separate the class implementations by file, like this: 作为一名经验丰富的C / C ++开发人员,我最有意义的是用文件分隔类实现,如下所示:

gui/MainWindow.py
gui/Widget1.py
gui/Widget2.py

Where, in the above, the specification of the MainWindow class would be in MainWindow.py . 在上面的地方, MainWindow类的规范将在MainWindow.py If I lay the files out in this way, however, then the syntax to get at those classes looks like: 但是,如果我以这种方式放置文件,那么获取这些类的语法如下所示:

import gui
w = gui.MainWindow.MainWindow()

which seems redundant. 这似乎是多余的。 A way around this limitation is to edit gui/__init__.py to say: 解决这个限制的方法是编辑gui/__init__.py来说:

from gui.MainWindow import *
from gui.Widget1 import *
from gui.Widget2 import *

which brings the classes into the gui module namespace. 它将类带入gui模块命名空间。 I can then access them as follows: 然后我可以按如下方式访问它们:

w = gui.MainWindow()

Is this typically done? 通常这样做吗? Does it have sufficient Pythonicity to be considered appropriate in the community? 它是否有足够的Pythonicity被认为适合社区? One drawback that I can see is that I need to be sure to keep gui/__init__.py as I add new submodules to the gui module; 我可以看到的一个缺点是,当我向gui模块添加新的子模块时,我需要确保保留gui/__init__.py ; I don't like manual steps like that. 我不喜欢这样的手动步骤。

Thoughts and/or suggestions of how to better address this would be great. 关于如何更好地解决这个问题的想法和/或建议会很棒。

不要导入* (除非您确定不存在冲突;此规则可以针对作者进行修改),但当然这是一个可接受的解决方案。

Probably you have noted these PEPs and documentation sites before: 您可能之前已经注意到这些PEP和文档站点:

So the only thing I can add to this is not to use import * . 所以我唯一可以添加的就是不使用import * One example: 一个例子:

>>> from pylab import *
>>> any(False for i in range(5))
True

While you validly argue that you know what you are doing. 虽然你有效地争辩说你知道自己在做什么。 You cannot assume that all of the potential re-users that import * from your package know what they're shadowing while they tear down the final namespace barrier between their and your code. 你不能假设从你的包中import *所有潜在重新用户都知道他们在他们和你的代码之间拆除最终名称空间障碍时所隐藏的内容。 This gives nasty errors. 这给出了令人讨厌的错误。 See also: 也可以看看:

Now what happens when the user writes from sound.effects import * ? 现在当用户from sound.effects import *写入时会发生什么? Ideally, one would hope that this somehow goes out to the filesystem, finds which submodules are present in the package, and imports them all. 理想情况下,人们希望以某种方式传递给文件系统,找到包中存在哪些子模块,并将它们全部导入。 This could take a long time and importing sub-modules might have unwanted side-effects that should only happen when the sub-module is explicitly imported. 这可能需要很长时间,导入子模块可能会产生不必要的副作用,这种副作用只有在显式导入子模块时才会发生。 Docs 文件

and

(import * is not an option ;-) PEP328 (导入*不是一个选项;-) PEP328

and

Namespaces are one honking great idea -- let's do more of those! 命名空间是一个很棒的主意 - 让我们做更多的事情吧! PEP20 PEP20

But these are only guidelines/recommendations/personal preferences, and there certainly exist edge cases when these do not apply. 但这些只是指导方针/建议/个人偏好,当这些不适用时肯定存在边缘情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM