模块导入和Python中的__init__.py [英] module imports and __init__.py in Python

查看:272
本文介绍了模块导入和Python中的__init__.py的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解Python(v2.7)导入机制的最佳实践。我有一个项目已经开始增长一点,让我说我的代码组织如下:

I am trying to understand what the best practices are with regards to Python's (v2.7) import mechanics. I have a project that has started to grow a bit and lets say my code is organised as follows:

foo/
    __init__.py
    Foo.py
    module1.py
    module2.py
    module3.py

包裹名称是 foo ,在它下面我有模块 Foo.py 其中包含类 Foo 的代码。因此,我对包,模块和类使用相同的名称,这可能不是很聪明的开始。

The package name is foo and underneath it I have module Foo.py which contains code for the class Foo. Hence I am using the same name for the package, module and class which might not be very clever to start with.

__ init __。py 为空且类 Foo 需要导入 module1,module2和module3 因此是我<$的一部分c $ c> Foo.py 文件如下:

__init__.py is empty and class Foo needs to import module1, module2 and module3 hence part of my Foo.py file looks like:

# foo/Foo.py

import module1
import module2
import module3

class Foo(object):
    def __init__(self):
....
....
if __name__ == '__main__':
    foo_obj = Foo()

但是后来我重新考虑了这一点,我认为在 __ init __。py 文件中包含所有导入会更好。因此我的 __ init __。py 现在看起来像:

However I later revisited this and I thought it would be better to have all imports in the __init__.py file. Hence my __init__.py now looks like:

# foo/__init__.py

import Foo
import module1
import module2
import module3
....
....

和我的 Foo.py 只需要导入 foo

# foo/Foo.py

import foo

虽然这看起来很方便,因为它是一个单行,我有点担心它可能创造循环进口。我的意思是当脚本 Foo.py 运行时,它将导入它可以的所有内容,然后 __ init __。py 将被调用,它将再次导入 Foo.py (这是正确的吗?)。另外,对于包,模块和类使用相同的名称会让事情变得更加混乱。

While this looks convenient since it is an one liner, I am a bit worried that it might be creating circular imports. What I mean is that when the script Foo.py is run it will import everything it can and then __init__.py will be called which will import Foo.py again (is that correct?). Additionally using the same name for package, module and class makes things more confusing.

我的方式是否有意义?或者我是在寻找麻烦?

Does it make sense the way I have done it? Or am I asking for trouble?

推荐答案

如果只是坚持一些流行的话,你可以采取一些措施来改善你的组织python约定和标准。

A couple things you could do to improve your organizaton, if only to adhere to some popular python conventions and standards.

如果您搜索此主题,您将不可避免地遇到推荐 PEP8 指南。这些是组织python代码的事实规范标准。

If you search this topic, you will inevitably run across people recommending the PEP8 guidelines. These are the de facto canonical standards for organizing python code.


模块应该有简短的全小写名称。如果提高可读性,则下划线可以是模块名称中使用的
。 Python包
也应该有简短的全小写名称,但不鼓励使用
下划线。

Modules should have short, all-lowercase names. Underscores can be used in the module name if it improves readability. Python packages should also have short, all-lowercase names, although the use of underscores is discouraged.

根据这些指导原则,您应该对项目模块进行命名和组织:

Based on these guidelines, you're project modules should be named and organized thusly:

foo/
    __init__.py
    foo.py
    module1.py
    module2.py
    module3.py

我发现通常最好避免在 __ init __。py 中不必要地导入模块,除非你出于命名空间的原因这样做。例如,如果您希望包的名称空间看起来像这样

I find it's generally best to avoid importing modules unnecessarily in __init__.py unless you're doing it for namespace reasons. For example, if you want the namespace for your package to look like this

from foo import Foo

而不是

from foo.foo import Foo

然后将

from .foo import Foo

在你的 __初始化__。PY 。随着您的包越来越大,一些用户可能不想使用所有的子包和模块,因此强制用户通过在<$ c中隐式导入它们来等待加载所有这些模块是没有意义的。 $ C> __初始化__。PY 。此外,你必须考虑你是否想要 module1 module2 module3 作为外部API的一部分。它们仅由 Foo 使用,而不是针对最终用户?如果它们仅在内部使用,则不要将它们包含在 __ init __。py

in your __init__.py. As your package gets larger, some users may not want to use all of the sub-packages and modules, so it doesn't make sense to force the user to wait for all those modules to load by implicitly importing them in your __init__.py. Also, you have to consider whether you even want module1, module2, and module3 as part of your external API. Are they only used by Foo and not intended to be for end users? If they're only used internally, then don't include them in the __init__.py

我会还建议使用绝对或显式相对导入来导入子模块。例如,在 foo.py

I'd also recommend using absolute or explicit relative imports for importing sub-modules. For example, in foo.py

from foo import module1
from foo import module2
from foo import module3



显式相对



Explicit Relative

from . import module1
from . import module2
from . import module3

这将防止其他软件包和模块出现任何可能的命名问题。如果您决定支持Python3,它也会更容易,因为Python3不支持您当前使用的隐式相对导入语法。

This will prevent any possible naming issues with other packages and modules. It will also make it easier if you decide to support Python3, since the implicit relative import syntax you're currently using is not supported in Python3.

此外,您的文件内包通常不应包含

Also, files inside your package generally shouldn't contain a

if __name__ == '__main__'

这是因为将文件作为脚本运行意味着它不会被视为它所属的包的一部分,因此它将无法做相对进口。

This is because running a file as a script means it won't be considered part of the package that it belongs to, so it won't be able to make relative imports.

向用户提供可执行脚本的最佳方法是使用 scripts console_scripts 的功能setuptools的 。您组织脚本的方式可能会有所不同,具体取决于您使用的方法,但我通常会像这样组织我的:

The best way to provide executable scripts to users is by using the scripts or console_scripts feature of setuptools. The way you organize your scripts can be different depending on which method you use, but I generally organize mine like this:

foo/
    __init__.py
    foo.py
    ...
scripts/
     foo_script.py
setup.py

这篇关于模块导入和Python中的__init__.py的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆