python基础:模块和包

一 模块和包

我们常常编辑保存的py文件就是一个个模块,模块名就是文件名不要后缀.py

包是模块的集合,也可以将包看作一个目录,但该目录必须包含文件__init__.py(该文件可为空或有其它内容),python才会将该目录当作包来处理

二 模块和包的导入

1 模块的导入

(1)导入形式1 import module_namexxxx

此操作不会直接把 module_name 中定义的函数和类等添加到当前模块的命名空间,只是会将模块名称module_name添加进来,通过使用导入模块的的模块名称,我们才能使用其中的函数

模块中包含各种函数及类等定义,还有可执行语句,导入模块时,这些可执行语句会被执行
如下
teste.py
image

testf.py
image
执行testf.py
image

可以看到,打印txt内容作为导入模块的可执行语句在import xx时被执行了。直接执行导入模块的定义的函数时报错了,必须结合使用导入模块名和函数

(2) 导入形式2 from module_namexxxx import xxxx

这种形式的作用与直接只用import的形式相反,它会将被导入模块的内容xxx直接加载到当前模块的命名空间中,所以可直接使用被导入的内容如定义的函数、变量等,但被导入模块的模块名不会加载到当前命名空间,所以被导入的模块名不能直接使用

修改下testf.py 如下
image
执行testf.py
image

可以看到,在import teste时,teste中的可执行语句即打印txt文件内容的语句依然被执行了,可直接使用被导入的teste中定义的函数,但是却不能使用模块名teste,因为加载到当前模块的是teste中定义的test函数,而不是模块名称teste

from module_namexx import *

这种方式会导入module中所有不以下划线(_)开头的内容,官方建议少使用,因为它可能会覆盖当前模块中相同的内容

(3) 给导入的内容修改名称

import module_namexx as new_name
from module_namexx import xxxx as new_name
用as关键字可以修改导入内容的名称,这样,原名称就不能使用了

(4)存在导入情况时,python在哪里去寻找模块

如下, 官网说得和详细
image
首先是在python的内置模块中去找,如果不属于内置模块,就会去sys.path给给出的位置中去寻找,其中最常见的就是运行py文件时所在的目录,python会该目录放在sys.path的开头

我们也可以打印下sys.path的值,看具体是那些位置 ,注意,在不同路径下运行py文件打印出来的值是不一样的
image

2 在包中导入内容

看一个官网的例子
image
明显 sound是一个包,下面还有3个子包formats、effects、filters,每个包中都有各自的模块

(1)import的形式

用该形式可以从包中导入模块
比如现在我有一个test.py文件,该文件引用了sound包中的一些模块,则该文件中可以这样写

import sound.effects.echo

#使用时不能直接用echo,必须通过导入的全路径来使用
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

(2) from xxx import xxx的形式

test.py中可以这样写

from sound.effects import echo

#使用时直接用echo
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

与模块中的使用一样,from的形式也可以导入模块中定义的内容,而不仅仅是导入模块

from sound.effects.echo import function

import xxx.xxxx.xxx时,除去最后一项xxx,每一个xxx都必须是包名,最后一项可以是模块名或包名。但不能是模块中定义的函数、类、变量

from xxxx.xxx import xxx ,最后一个xxx可以是模块和包,也可以是模块中定义的函数、类、变量

(3)导入包时 使用from xxx import *

例如from sound.effects import *,官网上说这样也许并不会导入effects中所有的子模块,因为内容过多的话就会花费很长时间,内容较少时应该没有问题的,这个问题还没有实印证过。

不过依然不建议直接使用from xxx import *,即使导入没有问题也可能存在我们不知道的覆盖问题

官网建议是在__init__.py中定义变量__all__,例如,sound/effects/init.py

__all__ = ["echo", "surround", "reverse"]

这样在test.py中使用from sound.effects import * 将导入 sound.effects 包的三个命名子模块

注意,__all__中所定义的内容可以是所在包的模块名,也可以是__init__文件中定义函数、变量
image
如上,sound.effects import * 将只导入 echo 和 surround 这两个子模块,不会导入 reverse 子模块,因为它被本地定义的 reverse 函数所覆盖

3 总结

import xxx时,要使用xxx里面的内容时,必须把前面的xxx带上
from xxx import xxx,可以直接使用import后的xxx,不必带上前面的模块名或包名

尽量不要使用from xxx import *,这样可能会覆盖当前模块的同名内容,还可能会发生其他未知的意外情况

posted @   工作手记  阅读(35)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示