Python - 为什么我可以在没有 __init__.py 的情况下导入模块?
Python - why can I import modules without __init__.py at all?
我是 Python 的新手,我仍然不明白为什么我们需要 __init__.py
文件来导入模块。我已经完成了其他问题和答案,例如 this.
让我感到困惑的是,我可以导入我的模块 而无需 __init__py
,所以 我为什么需要它 ?
我的例子,
index.py
modules/
hello/
hello.py
HelloWorld.py
index.py,
import os
import sys
root = os.path.dirname(__file__)
sys.path.append(root + "/modules/hello")
# IMPORTS MODULES
from hello import hello
from HelloWorld import HelloWorld
def application(environ, start_response):
results = []
results.append(hello())
helloWorld = HelloWorld()
results.append(helloWorld.sayHello())
output = "<br/>".join(results)
response_body = output
status = '200 OK'
response_headers = [('Content-Type', 'text/html'),
('Content-Length', str(len(response_body)))]
start_response(status, response_headers)
return [response_body]
modules/hello/hello.py,
def hello():
return 'Hello World from hello.py!'
modules/hello/HelloWorld.py,
# define a class
class HelloWorld:
def __init__(self):
self.message = 'Hello World from HelloWorld.py!'
def sayHello(self):
return self.message
结果,
Hello World from hello.py!
Hello World from HelloWorld.py!
只需要这两行,
root = os.path.dirname(__file__)
sys.path.append(root + "/modules/hello")
没有任何 __init__py
。有人可以解释为什么它以这种方式工作吗?
如果 __init__py
是正确的方法,我的代码中应该 do/change 是什么?
__init__.py
用于 软件包 。包包含相关模块的集合。如果您只有一个模块要使用,则不需要使用 __init__.py
;只需将单个 .py
文件放在系统路径中的某处即可导入它。
包的目的不仅仅是让您导入其中的模块。它是将模块组合在一起。这样做的主要好处是,如果模块在包内,则该模块可以使用相对导入从包中导入其他模块。如果你在同一个包中有 foo.py
和 bar.py
,那么 foo
可以只做 from . import bar
。这使得包内导入更紧凑,如果您重组包或更改其名称,则更容易重新组织。
此外,一个明显的好处是。 . .如果你把它做成一个包,你就不必每次想从它导入东西时都做 sys.path
的事情。
名为__init__.py
的文件用于将磁盘上的目录标记为Python 包目录。如果你有文件
modules/spam/__init__.py
modules/spam/module.py
和modules
在您的路径中,您可以将module.py
中的代码导入为
import spam.module
或
from spam import module
如果删除 __init__.py
文件,Python 将不再在该目录中查找子模块,因此尝试导入该模块将失败。
__init__.py
文件通常是空的,但可用于以更方便的名称导出包的选定部分,保存方便的函数等。在上面的示例中,init 模块的内容可以通过
访问
import spam
最后是官方文档对这个文件的描述:
需要 __init__.py
文件才能使 Python 处理
包含包的目录;这样做是为了防止
具有通用名称的目录,例如字符串,来自
无意中隐藏了稍后出现的有效模块
模块搜索路径。在最简单的情况下,__init__.py
可以
是一个空文件,但它也可以执行初始化代码
为包或设置 __all__
变量,稍后描述。
我认为这是一个很好的'answer',因为我不明白。
myMath/
__init__.py
adv/
__init__.py
sqrt.py
fib.py
add.py
subtract.py
multiply.py
divide.py
myMath/__init__.py
from add import add
from divide import division
from multiply import multiply
from subtract import subtract
from adv.fib import fibonacci
from adv.sqrt import squareroot
index.py
import sys
sys.path.append('C:\Users\mdriscoll\Documents')
import mymath
print mymath.add(4,5)
print mymath.division(4, 2)
print mymath.multiply(10, 5)
print mymath.fibonacci(8)
print mymath.squareroot(48)
我认为这可能是由于您使用的 Python 版本所致。我做了一些实验,发现具有以下结构:
jedrzej@jedrzej-UX303LB ~/temp $ tree .
.
├── main.py
└── packages
├── file.py
└── file.pyc
1 directory, 5 files
main.py的内容:
import packages.file as p
p.fun()
和file.py的内容:
import sys
def fun():
print(sys.path)
当我使用 Python 2.7.12 执行 main.py
时,我得到 ImportError
,而使用 Python 3.5.2 执行 main.py
只是工作。
在 packages 目录中添加 __init__.py
后,代码适用于两个版本的 Python。
基于 link:自Python 3.3
Allowing implicit namespace packages means that the requirement to provide an __init__.py
file can be dropped completely
我是 Python 的新手,我仍然不明白为什么我们需要 __init__.py
文件来导入模块。我已经完成了其他问题和答案,例如 this.
让我感到困惑的是,我可以导入我的模块 而无需 __init__py
,所以 我为什么需要它 ?
我的例子,
index.py
modules/
hello/
hello.py
HelloWorld.py
index.py,
import os
import sys
root = os.path.dirname(__file__)
sys.path.append(root + "/modules/hello")
# IMPORTS MODULES
from hello import hello
from HelloWorld import HelloWorld
def application(environ, start_response):
results = []
results.append(hello())
helloWorld = HelloWorld()
results.append(helloWorld.sayHello())
output = "<br/>".join(results)
response_body = output
status = '200 OK'
response_headers = [('Content-Type', 'text/html'),
('Content-Length', str(len(response_body)))]
start_response(status, response_headers)
return [response_body]
modules/hello/hello.py,
def hello():
return 'Hello World from hello.py!'
modules/hello/HelloWorld.py,
# define a class
class HelloWorld:
def __init__(self):
self.message = 'Hello World from HelloWorld.py!'
def sayHello(self):
return self.message
结果,
Hello World from hello.py!
Hello World from HelloWorld.py!
只需要这两行,
root = os.path.dirname(__file__)
sys.path.append(root + "/modules/hello")
没有任何 __init__py
。有人可以解释为什么它以这种方式工作吗?
如果 __init__py
是正确的方法,我的代码中应该 do/change 是什么?
__init__.py
用于 软件包 。包包含相关模块的集合。如果您只有一个模块要使用,则不需要使用 __init__.py
;只需将单个 .py
文件放在系统路径中的某处即可导入它。
包的目的不仅仅是让您导入其中的模块。它是将模块组合在一起。这样做的主要好处是,如果模块在包内,则该模块可以使用相对导入从包中导入其他模块。如果你在同一个包中有 foo.py
和 bar.py
,那么 foo
可以只做 from . import bar
。这使得包内导入更紧凑,如果您重组包或更改其名称,则更容易重新组织。
此外,一个明显的好处是。 . .如果你把它做成一个包,你就不必每次想从它导入东西时都做 sys.path
的事情。
名为__init__.py
的文件用于将磁盘上的目录标记为Python 包目录。如果你有文件
modules/spam/__init__.py
modules/spam/module.py
和modules
在您的路径中,您可以将module.py
中的代码导入为
import spam.module
或
from spam import module
如果删除 __init__.py
文件,Python 将不再在该目录中查找子模块,因此尝试导入该模块将失败。
__init__.py
文件通常是空的,但可用于以更方便的名称导出包的选定部分,保存方便的函数等。在上面的示例中,init 模块的内容可以通过
import spam
最后是官方文档对这个文件的描述:
需要 __init__.py
文件才能使 Python 处理
包含包的目录;这样做是为了防止
具有通用名称的目录,例如字符串,来自
无意中隐藏了稍后出现的有效模块
模块搜索路径。在最简单的情况下,__init__.py
可以
是一个空文件,但它也可以执行初始化代码
为包或设置 __all__
变量,稍后描述。
我认为这是一个很好的'answer',因为我不明白。
myMath/
__init__.py
adv/
__init__.py
sqrt.py
fib.py
add.py
subtract.py
multiply.py
divide.py
myMath/__init__.py
from add import add
from divide import division
from multiply import multiply
from subtract import subtract
from adv.fib import fibonacci
from adv.sqrt import squareroot
index.py
import sys
sys.path.append('C:\Users\mdriscoll\Documents')
import mymath
print mymath.add(4,5)
print mymath.division(4, 2)
print mymath.multiply(10, 5)
print mymath.fibonacci(8)
print mymath.squareroot(48)
我认为这可能是由于您使用的 Python 版本所致。我做了一些实验,发现具有以下结构:
jedrzej@jedrzej-UX303LB ~/temp $ tree .
.
├── main.py
└── packages
├── file.py
└── file.pyc
1 directory, 5 files
main.py的内容:
import packages.file as p
p.fun()
和file.py的内容:
import sys
def fun():
print(sys.path)
当我使用 Python 2.7.12 执行 main.py
时,我得到 ImportError
,而使用 Python 3.5.2 执行 main.py
只是工作。
在 packages 目录中添加 __init__.py
后,代码适用于两个版本的 Python。
基于
Allowing implicit namespace packages means that the requirement to provide an
__init__.py
file can be dropped completely