05-import-包

AffettoIris 2023-2-21 2,606 2/21

模块

import

我们如何实现自己写的公共库函数文件,能像他人的库一样import呢?:在执行文件2.py的同级目录下或者sys.path目录下,有a.py

05-import-包

那么2.py直接import 文件名即可

05-import-包

模块也可以引入其他模块:

05-import-包

需要注意的是,和php一样,import 文件名或者from 文件名 import *都是全部引入,包括非函数代码块,这意味着会执行非函数内容:

05-import-包

所以优秀的程序员在写模块文件时,会:

05-import-包

Python中的模块在创建之初会自动加载一些内建变量,__name__就是其中之一。__name__在本文件内取值为__main__

原理:import时解释器是怎样找到对应的文件的呢?

这就涉及到 Python 的搜索路径,搜索路径是由一系列目录名组成的,Python 解释器就依次从这些目录中去寻找所引入的模块。这看起来很像环境变量,事实上,也可以通过定义环境变量的方式来确定搜索路径。搜索路径被存储在 sys 模块中的 path 变量。sys.path的输出的第0项是当前目前,可能显示’‘或者显示绝对路径。

import sys

print(sys.path)
"""
['C:\\Users\\iris\\Desktop\\bilibili\\python菜鸟教程', 
'C:\\Users\\iris\\Anaconda2\\envs\\python39.zip', 
'C:\\Users\\iris\\Anaconda2\\envs\\DLLs', 
'C:\\Users\\iris\\Anaconda2\\envs\\lib', 
'C:\\Users\\iris\\Anaconda2\\envs', 
'C:\\Users\\iris\\Anaconda2\\envs\\lib\\site-packages', 
'C:\\Users\\iris\\Anaconda2\\envs\\lib\\site-packages\\win32', 
'C:\\Users\\iris\\Anaconda2\\envs\\lib\\site-packages\\win32\\lib', 
'C:\\Users\\iris\\Anaconda2\\envs\\lib\\site-packages\\Pythonwin']
"""

小技巧:如果经常用某函数,可以赋它一个本地的名称

import random

a = random.random() # 加()就是执行random.random()了,a=0.5680807127568146
b = random.random # 不加()就是取别名,毕竟没执行
print(b()) # 0.4113116876653664

包是什么样的

包方便了相似功能或目的的文件(或曰模块)聚集在同一目录(即包)下,也方便了相似目的的包聚集在同一父包下。例如下图处理声音文件和数据的模块们,有部分模块聚集在formats包下,部分模块聚集在effects包下,部分模块聚集在filters包下;formats包、effects包、filters包同一聚集在sound包下:

05-import-包

由于使用模块时采用sound.effects.echo、sound.effects.echo.fun()格式,所以你不用担心不同模块之间的重名的变量相互影响。在导入一个包的时候,Python 会根据 sys.path 中的目录来寻找这个包中包含的子目录。目录只有包含一个叫做 init.py 的文件才会被认作是一个包,主要是为了避免一些滥俗的名字(比如叫做 string)不小心的影响搜索路径中的有效模块;init.py可以是空文件。

使用不同包下的模块

例如import sound.effects.echo,必须使用全名去访问模块的功能:

sound.effects.echo.echofilter(input, output, delay=0.7, atten=4) # 对的
echo.echofilter(input, output, delay=0.7, atten=4) # 错的,最好理解的解释是,万一引入的另一包也有echo.py,echo.py也有echofilter(),这计算机不就被二义性了么

但是from sound.effects import echo导入子模块: echo不需要那些冗长的前缀:

echo.echofilter(input, output, delay=0.7, atten=4)

而且也不支持sound.effects.echo.echofilter(input, output, delay=0.7, atten=4),显示sound is not defined。试过了,

from sound1.effects import echo
from sound2.effects import echo

echo.echofilter() # 执行的是sound2.effects.echo.echofilter()

也可以

from sound1.effects.echo import echofilter

echofilter(input, output, delay=0.7, atten=4)

总结

 from package import 子包/子模块/函数//变量

优化win上的from package import *

因为 Windows 是一个不区分大小写的系统,所以模块名(文件名) echo.py 还是 Echo.py,或者是 ECHO.py,在from sound.effects import * 时都,具体到sound.effects.echo.py文件时,不确定是from sound.effects import ECHO还是from sound.effects import echo还是啥。

为了解决这个问题,我们提出了在包定义文件 __init__.py里设置一个索引, __all__ 是一个列表变量,在使用 from package import * 的时候就会把这个列表中的所有名字作为包内容导入。
例如sounds/effects/__init__.py 中包含如下代码
__all__ = ["echo", "surround", "reverse"]
# __all__ 可以不写,不写时from package 导入全部内容。mport *导入全部内容。
作为包的作者,可别忘了在更新包之后保证 __all__ 也更新了啊。
- THE END -

AffettoIris

10月16日15:56

最后修改:2023年10月16日
0

非特殊说明,本博所有文章均为博主原创。

共有 0 条评论