在导入代码的各种方法中,有些方法比其他方法更适合使用吗?这个链接http://effbot.org/zone/import-confusion.htm简而言之 说明
from foo.bar import MyClass
在正常情况下,不是导入MyClass的首选方式,除非您知道自己在做什么。 (相反,更好的方式是:
import foo.bar as foobaralias
然后在代码中,访问MyClass使用
foobaralias.MyClass
)
简而言之,上面提到的链接似乎是说通常更好地从模块中导入所有内容,而不仅仅是模块的一部分。
然而,我链接的那篇文章真的很旧。
我也听说,至少在Django项目的上下文中,更好的是只导入你想要使用的类,而不是整个模块。据说这种形式有助于避免循环导入错误或至少使django导入系统不那么脆弱。有人指出,Django自己的代码似乎更喜欢“从x import y”而不是“import x”。
假设我正在处理的项目没有使用__init__.py
的任何特殊功能...(我们所有的__init__.py
文件都是空的),我应该支持哪种导入方法,为什么?
答案 0 :(得分:13)
首先,主要的进口规则:永远不要使用from foo import *
。
本文正在讨论周期性进口问题,这种问题至今仍存在于结构不良的代码中。我不喜欢周期性进口;他们的存在是一个强烈的迹象,表明某些模块做得太多,需要分开。如果出于某种原因,您需要使用无法重新排列的循环导入代码,import foo
是唯一的选择。
对于大多数情况,import foo
和from foo import MyClass
之间没有太大区别。我更喜欢第二种,因为涉及的打字较少,但我可以使用第一种打字的原因有几个:
模块和类/值具有不同的名称。当导入值的名称与模块无关时,读者可能很难记住特定导入的来源。
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
答案 1 :(得分:5)
对我来说,这取决于具体情况。如果它是一个唯一命名的方法/类(即,不是process()
或类似的东西),并且你将使用它 lot ,那么保存输入并且只做{{1 }}。
如果你从一个模块导入多个东西,最好只导入模块,然后执行from foo import MyClass
等,以保持命名空间的清洁。
你也说过
据说这种形式有助于避免循环导入错误,或者至少使django导入系统不那么脆弱。有人指出,Django自己的代码似乎更喜欢“从x import y”而不是“import x”。
我不知道这种或那种方式如何有助于防止循环进口。原因是,即使您执行module.bar, module.foo, module.baz
,也会导入所有from x import y
。仅x
被引入当前命名空间,但处理整个模块y
。试试这个例子:
在test.py中,输入以下内容:
x
然后在'runme.py'中,输入:
def a():
print "a"
print "hi"
def b():
print "b"
print "bye"
然后执行from test import b
b()
您将看到以下输出:
python runme.py
所以即使您只导入了hi
bye
b
答案 2 :(得分:2)
后者的优点是MyClass的起源更明确。前者将MyClass放在当前名称空间中,因此代码只能使用不合格的MyClass。因此,对于阅读MyClass定义的代码的人来说,这是不太明显的。