在Python源目录中
它是一个整体的一部分。这是文档。
The
__init__.py files are required to make Python treat the directories as containing packages; this is done to prevent directories with a common name, such asstring , from unintentionally hiding valid modules that occur later (deeper) on the module search path. In the simplest case,__init__.py can just be an empty file, but it can also execute initialization code for the package or set the__all__ variable, described later.
名为
1 2 | mydir/spam/__init__.py mydir/spam/module.py |
并且
1 | import spam.module |
或
1 | from spam import module |
如果删除
1 | import spam |
在此基础上
除了将目录标记为Python包并定义
一个例子
下面是我的一个项目中的一个例子,其中我经常导入一个名为
1 2 3 4 5 | database/ __init__.py schema.py insertions.py queries.py |
My
1 2 3 4 5 6 7 | import os from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine engine = create_engine(os.environ['DATABASE_URL']) Session = sessionmaker(bind=engine) |
因为我在这里定义了
1 2 | from database import Session session = Session() |
当然,这是一个小小的便利——另一种方法是在一个像"create_session"这样的新文件中定义
1 2 | from database.create_session import Session session = Session() |
进一步阅读
reddit上有一个非常有趣的帖子,介绍了
What's your opinion on what to include in __init__.py ? from Python
大多数意见似乎是
为了方便:其他用户不需要知道函数在包层次结构中的确切位置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | your_package/ __init__.py file1.py/ file2.py/ ... fileN.py # in __init__.py from file1 import * from file2 import * ... from fileN import * # in file1.py def add(): pass |
然后其他人可以调用add() by
1 | from your_package import add |
不知道file1
1 | from your_package.file1 import add |
如果你想要初始化一些东西;例如,日志(应该放在顶层):
1 2 | import logging.config logging.config.dictConfig(Your_logging_config) |
此外,这是模块中要加载的第一个文件,因此您可以使用它来执行每次加载模块时要运行的代码,或者指定要导出的子模块。
自Python 3.3以来,
检查PEP 420:隐式名称空间包:
Native support for package directories that don’t require
__init__.py marker files and can automatically span multiple path segments (inspired by various third party approaches to namespace packages, as described in PEP 420)
这是测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | $ mkdir -p /tmp/test_init $ touch /tmp/test_init/module.py /tmp/test_init/__init__.py $ tree -at /tmp/test_init /tmp/test_init ├── module.py └── __init__.py $ python3 >>> import sys >>> sys.path.insert(0, '/tmp') >>> from test_init import module >>> import test_init.module $ rm -f /tmp/test_init/__init__.py $ tree -at /tmp/test_init /tmp/test_init └── module.py $ python3 >>> import sys >>> sys.path.insert(0, '/tmp') >>> from test_init import module >>> import test_init.module |
引用:https://docs.python.org/3/whatsnew/3.3.html#pep-420-implicit-namespace-packageshttps://www.python.org/dev/peps/pep-0420/Python 3中的包是否不需要.py ?
在Python中,包的定义非常简单。与Java一样,层次结构和目录结构是相同的。但是您必须在包中包含
1 2 3 4 5 6 7 8 9 10 | package_x/ |-- __init__.py |-- subPackage_a/ |------ __init__.py |------ module_m1.py |-- subPackage_b/ |------ __init__.py |------ module_n1.py |------ module_n2.py |------ module_n3.py |
如果我们在module_n1中添加一个函数:
1 2 3 | def function_X(): print"function_X in module_n1" return |
在运行:
1 2 3 4 | >>>from package_x.subPackage_b.module_n1 import function_X >>>function_X() function_X in module_n1 |
然后,我们按照层次结构包调用module_n1函数。我们可以像这样在subPackage_b中使用
1 | __all__ = ['module_n2', 'module_n3'] |
在运行:
1 2 3 4 5 6 | >>>from package_x.subPackage_b import * >>>module_n1.function_X() Traceback (most recent call last): File"<stdin>", line 1, in <module> ImportError: No module named module_n1 |
因此,使用* import,模块包受制于
对于喜欢阅读代码的人,我在这里添加了两位炼金术士的注释。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | $ find /tmp/mydir/ /tmp/mydir/ /tmp/mydir//spam /tmp/mydir//spam/__init__.py /tmp/mydir//spam/module.py $ cd ~ $ python >>> import sys >>> sys.path.insert(0, '/tmp/mydir') >>> from spam import module >>> module.myfun(3) 9 >>> exit() $ $ rm /tmp/mydir/spam/__init__.py* $ $ python >>> import sys >>> sys.path.insert(0, '/tmp/mydir') >>> from spam import module Traceback (most recent call last): File"<stdin>", line 1, in <module> ImportError: No module named spam >>> |
虽然Python没有
它指定一个包应该被视为一个模块,因此包括它(即使它是空的)。
也有一种情况,你可以实际使用
假设您有以下文件结构:
1 2 | main_methods |- methods.py |
其中包括:
1 2 | def foo(): return 'foo' |
要使用
1 2 3 | from main_methods.methods import foo # Call with foo() from main_methods import methods # Call with methods.foo() import main_methods.methods # Call with main_methods.methods.foo() |
也许您需要(或希望)将
如果您将
1 2 | import main_methods print(main_methods.foo()) # Prints 'foo' |
这是因为
一些Python包实际上是这样做的。JSON就是一个例子,其中运行
Source code:
Lib/json/__init__.py
它便于导入其他python文件。当您将此文件放在包含其他py文件的目录中(比如stuff)时,您可以执行导入stuff.other之类的操作。
1 2 3 4 5 6 | root\ stuff\ other.py morestuff\ another.py |
如果目录中没有这个