Python(和 Django)最佳导入实践
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1704058/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python (and Django) best import practices
提问by Eddified
Out of the various ways to import code, are there some ways that are preferable to use, compared to others? This link http://effbot.org/zone/import-confusion.htmin short states that
在导入代码的各种方法中,与其他方法相比,是否有一些方法更适合使用?这个链接http://effbot.org/zone/import-confusion.htm简而言之
from foo.bar import MyClass
is not the preferred way to import MyClass under normal circumstances or unless you know what you are doing. (Rather, a better way would like:
在正常情况下或除非您知道自己在做什么,否则不是导入 MyClass 的首选方式。(相反,更好的方法是:
import foo.bar as foobaralias
and then in the code, to access MyClass use
然后在代码中,访问 MyClass 使用
foobaralias.MyClass
)
)
In short, it seems that the above-referenced link is saying it is usuallybetter to import everything from a module, rather than just parts of the module.
简而言之,上面引用的链接似乎是说从模块导入所有内容通常更好,而不仅仅是模块的一部分。
However, that article I linked is really old.
但是,我链接的那篇文章真的很旧。
I've also heard that it is better, at least in the context of Django projects, to instead only import the classes you want to use, rather than the whole module. It has been said that this form helps avoid circular import errors or at least makes the django import system less fragile. It was pointed out that Django's own code seems to prefer "from x import y" over "import x".
我还听说,至少在 Django 项目的上下文中,最好只导入您想要使用的类,而不是整个模块。据说这种形式有助于避免循环导入错误或至少使 django 导入系统不那么脆弱。有人指出,Django 自己的代码似乎更喜欢“from x import y”而不是“import x”。
Assuming the project I am working on doesn't use any special features of __init__.py
... (all of our __init__.py
files are empty), what import method should I favor, and why?
假设我正在处理的项目不使用...的任何特殊功能__init__.py
(我们所有的__init__.py
文件都是空的),我应该支持哪种导入方法,为什么?
采纳答案by Jay P.
For me, it's dependent on the situation. If it's a uniquely named method/class (i.e., not process()
or something like that), and you're going to use it a lot, then save typing and just do from foo import MyClass
.
对我来说,这取决于情况。如果它是一个唯一命名的方法/类(即不process()
或类似的东西),你要使用它很多,然后保存打字,只是做from foo import MyClass
。
If you're importing multiple things from one module, it's probably better to just import the module, and do module.bar, module.foo, module.baz
, etc., to keep the namespace clean.
如果您从一个模块导入多个内容,最好只导入该模块,然后执行module.bar, module.foo, module.baz
等等,以保持命名空间干净。
You also said
你还说
It has been said that this form helps avoid circular import errors or at least makes the django import system less fragile. It was pointed out that Django's own code seems to prefer "from x import y" over "import x".
据说这种形式有助于避免循环导入错误或至少使 django 导入系统不那么脆弱。有人指出,Django 自己的代码似乎更喜欢“from x import y”而不是“import x”。
I don't see how one way or the other would help prevent circular imports. The reason is that even when you do from x import y
, ALL of x
is imported. Only y
is brought into the current namespace, but the entire module x
is processed. Try out this example:
我不知道一种或另一种方式如何有助于防止循环导入。原因是,即使您这样做from x import y
, ALL ofx
也会被导入。Onlyy
被带入当前命名空间,但整个模块都x
被处理。试试这个例子:
In test.py, put the following:
在 test.py 中,输入以下内容:
def a():
print "a"
print "hi"
def b():
print "b"
print "bye"
Then in 'runme.py', put:
然后在“runme.py”中,输入:
from test import b
b()
Then just do python runme.py
然后就做 python runme.py
You'll see the following output:
您将看到以下输出:
hi
bye
b
So everything in test.py was run, even though you only imported b
因此 test.py 中的所有内容都已运行,即使您只导入了 b
回答by John Millikin
First, and primary, rule of imports: never ever use from foo import *
.
首先,也是主要的导入规则:永远不要使用from foo import *
.
The article is discussing the issue of cyclical imports, which still exists today in poorly-structured code. I dislike cyclical imports; their presence is a strong sign that some module is doing too much, and needs to be split up. If for whatever reason you need to work with code with cyclical imports which cannot be re-arranged, import foo
is the only option.
这篇文章正在讨论循环导入的问题,该问题今天仍然存在于结构不良的代码中。我不喜欢周期性进口;它们的存在是一个强烈的信号,表明某些模块做得太多,需要拆分。如果出于某种原因您需要使用无法重新排列的循环导入代码,这import foo
是唯一的选择。
For most cases, there's not much difference between import foo
and from foo import MyClass
. I prefer the second, because there's less typing involved, but there's a few reasons why I might use the first:
在大多数情况下,import foo
和之间没有太大区别from foo import MyClass
。我更喜欢第二种,因为涉及的打字较少,但我可能会使用第一种的原因有几个:
The module and class/value have different names. It can be difficult for readers to remember where a particular import is coming from, when the imported value's name is unrelated to the module.
- Good:
import myapp.utils as utils; utils.frobnicate()
- Good:
import myapp.utils as U; U.frobnicate()
- Bad:
from myapp.utils import frobnicate
- Good:
You're importing a lot of values from one module. Save your fingers, and reader's eyes.
- Bad:
from myapp.utils import frobnicate, foo, bar, baz, MyClass, SomeOtherClass, # yada yada
- Bad:
模块和类/值具有不同的名称。当导入值的名称与模块无关时,读者可能很难记住特定导入的来源。
- 好的:
import myapp.utils as utils; utils.frobnicate()
- 好的:
import myapp.utils as U; U.frobnicate()
- 坏的:
from myapp.utils import frobnicate
- 好的:
您正在从一个模块导入大量值。保存您的手指和读者的眼睛。
- 坏的:
from myapp.utils import frobnicate, foo, bar, baz, MyClass, SomeOtherClass, # yada yada
- 坏的:
回答by Grumdrig
The advantage of the latter is that the origin of MyClass is more explicit. The former puts MyClass in the current namespace so the code can just use MyClass unqualified. So it's less obvious to someone reading the code where MyClass is defined.
后者的好处是MyClass的起源更加明确。前者将 MyClass 放在当前命名空间中,因此代码可以仅使用不合格的 MyClass。因此,对于阅读定义 MyClass 的代码的人来说,这不太明显。