Python(和Django)最佳导入实践

时间:2009-11-09 21:42:36

标签: python django python-import

在导入代码的各种方法中,有些方法比其他方法更适合使用吗?这个链接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文件都是空的),我应该支持哪种导入方法,为什么?

3 个答案:

答案 0 :(得分:13)

首先,主要的进口规则:永远不要使用from foo import *

本文正在讨论周期性进口问题,这种问题至今仍存在于结构不良的代码中。我不喜欢周期性进口;他们的存在是一个强烈的迹象,表明某些模块做得太多,需要分开。如果出于某种原因,您需要使用无法重新排列的循环导入代码,import foo是唯一的选择。

对于大多数情况,import foofrom 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

,test.py中的所有内容都会运行

答案 2 :(得分:2)

后者的优点是MyClass的起源更明确。前者将MyClass放在当前名称空间中,因此代码只能使用不合格的MyClass。因此,对于阅读MyClass定义的代码的人来说,这是不太明显的。