Python(和Django)最佳导入实践

Edd*_*ied 21 python django python-import

在导入代码的各种方法中,有些方法比其他方法更适合使用吗?这个链接http://effbot.org/zone/import-confusion.htm简而言之

from foo.bar import MyClass
Run Code Online (Sandbox Code Playgroud)

在正常情况下,或者除非您知道自己在做什么,否则不是首选导入MyClass的方法.(相反,更好的方式是:

import foo.bar as foobaralias
Run Code Online (Sandbox Code Playgroud)

然后在代码中,访问MyClass使用

foobaralias.MyClass
Run Code Online (Sandbox Code Playgroud)

)

简而言之,似乎上面提到的链接说通常更好地从模块导入所有内容,而不仅仅是模块的一部分.

但是,我链接的那篇文章真的很旧.

我还听说,至少在Django项目的上下文中,更好的是只导入你想要使用的类,而不是整个模块.据说这种形式有助于避免循环导入错误或至少使django导入系统不那么脆弱.有人指出,Django自己的代码似乎更喜欢"从x import y"而不是"import x".

假设我正在处理的项目没有使用...的任何特殊功能__init__.py(我们所有的__init__.py文件都是空的),我应该支持哪种导入方法,为什么?

Joh*_*kin 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

  • 那么`来自myapp import utils; utils.frobnicate()`? (2认同)

小智 5

对我来说,这取决于具体情况.如果它是一个唯一命名的方法/类(即,不是process()或类似的东西),并且你将要使用它很多,那么保存输入就行了from foo import MyClass.

如果您从一个模块导入多个东西,最好只导入模块,并执行module.bar, module.foo, module.baz等操作以保持命名空间清洁.

你也说过

据说这种形式有助于避免循环导入错误或至少使django导入系统不那么脆弱.有人指出,Django自己的代码似乎更喜欢"从x import y"而不是"import x".

我不知道这种或那种方式如何有助于防止循环进口.原因是,即使你这样做from x import y,所有的x都是导入的.仅y进入当前名称空间,但处理整个模块x.试试这个例子:

在test.py中,输入以下内容:

def a():
    print "a"

print "hi"

def b():
    print "b"

print "bye"
Run Code Online (Sandbox Code Playgroud)

然后在'runme.py'中,放:

from test import b

b()
Run Code Online (Sandbox Code Playgroud)

然后就做 python runme.py

您将看到以下输出:

hi
bye
b
Run Code Online (Sandbox Code Playgroud)

因此,即使您只导入了test.py中的所有内容 b