模块
绝对导入和相对导入为Python包的组织提供了清晰的规则。明确的导入方式让代码的依赖关系更加清晰,避免了命名冲突。
# 绝对导入
from mypackage.submodule import function
# 相对导入
from .submodule import function
from ..parentmodule import other_function
模块
用模块管理函数,Python 中每个文件就代表了一个模块(module),
Python 会将所有 .py 结尾的文件认定为 Python 代码文件。
import,from,as
在使用函数的时候我们通过 import 关键字导入指定的模块:
module1.py
def foo():
print('hello, world!')
module2.py
def foo():
print('goodbye, world!')
test.py
from module1 import foo
# 输出hello, world!
foo()
from module2 import foo
# 输出goodbye, world!
foo()
name属性
有时候我们想将一个 .py 文件既当作脚本,又能当作模块用, 这个时候可以使用 name 这个属性。
PI = 3.14
def get_sum(lst):
"""
Sum the values in the list
:param lst:
:return:
"""
total = 0
for v in lst:
total = total + v
return total
上文保存为 ex.py
with open('ex.py', 'w') as f:
f.write("""
PI = 3.14
def get_sum(lst):
total = 0
for v in lst:
total = total + v
return total
""")
使用 ! 调用 shell 命令:
!cat ex.py
可以从 ex 模块中导入函数 get_sum 和变量:
from ex import PI, get_sum
print(PI) # 3.14
print(get_sum([2, 3])) # 5
# 可以使用 * 导入所有变量, 不提倡,因为可能覆盖一些已有的函数
# 删除文件:
import os
os.remove('ex.py')
模块导入顺序
通常情况下,当使用 import 语句导入模块后,Python 会按照以下顺序查找指定的模块文件:
前目录,即当前执行的程 序文件所在目录下查找;
到 PYTHONPATH(环境变量)下的每个目录中查找;
到 Python 默认的安装目录下查找。
以上所有涉及到的目录,都保存在标准模块 sys 的 sys.path 变量中,通过此变量我们可以看到指定程序文件支持查找的所有目录。换句话说,如果要导入的模块没有存储在 sys.path 显示的目录中,那么导入该模块并运行程序时,Python 解释器就会抛出 ModuleNotFoundError(未找到模块)异常。
解决“Python 找不到指定模块”的方法有 3 种,分别是:
向 sys.path 中临时添加模块文件存储位置的完整路径;
将模块放在 sys.path 变量中已包含的模块加载路径中;
设置 path 系统环境变量。
具体区别可以创建下面的文件解构来了解:
top/
├── __init__.py
├── second.py
└── second_copy.py
import sys
print(sys.argv)
from .second_copy import *
import sys
print(sys.argv)
两种运行脚本的方式,以及对应的输出 :
-
使用
python -m top.second
运行:PS C:\Users\jiang\Desktop> python -m top.second
['C:\\Users\\jiang\\Desktop\\top\\second.py']
['C:\\Users\\jiang\\Desktop\\top\\second.py']- 输出两次相同的
sys.argv
,显示脚本的完整路径。 - 没有错误,脚本正常运行。
- 输出两次相同的
-
直接运行
python top\second.py
:PS C:\Users\jiang\Desktop> python top\second.py
['top\\second.py']
Traceback (most recent call last):
File "C:\Users\jiang\Desktop\top\second.py", line 3, in <module>
from .second_copy import *
ImportError: attempted relative import with no known parent package- 仅输出了
sys.argv
一次,显示的是相对路径top\second.py
。 - 然后抛出了
ImportError
,提示“尝试进行相对导入,但没有已知的父包”。
- 仅输出了