本文介绍python的模块和包。
模块Modules
模块是一个包含一些python代码的文件。
from sales import calc_shipping,calc_tax
# 从模块sales中导入calc_shipping和calc_tax
# 也可以导入所有 from sales import *
# 导入所有是一个坏习惯,一般只导入我们所需的
calc_shipping()
calc_tax()
还有一种是导入整个模块
import sales
# 导入整个模块
sales.calc_shipping()
# 带上模块前缀使用
编译的python文件
__pycache__\文件夹下有已编译的python文件,比如sales.cpython-39.pyc文件。
下次运行时如果没有修改,可以直接运行不必重新编译,加快速度。注意,不是提升应用程序性能。
它是根据修改时间来判断的,如果对应py文件比pyc文件新,就表示py文件有更新,就重新编译。
程序的入口,比如app.py是不会存在已编译文件夹下的,入口程序每次都会被重新编译。
模块搜索路径
- 当前目录
- 预定义的一些目录,可以查看sys.pathimport sysprint(sys.path)
在执行import指令时,python将搜索这些目录,一旦找到就停止搜索。
包Packages
包是一个或多个模块的容器,对于文件系统来说,就是一个目录。该目录下必须有这个文件。
__init__.py
import ecommerce.sales
# ecommerce是包(文件夹目录),sales是模块(文件)
ecommerce.sales.calc_tax()
# 调用需带上前缀,有点杂乱
下面这种方式可能更好:
from ecommerce.sales import calc_tax
calc_tax()
上述方法,如果对象太多,也会变得很复杂,可以将模块作为对象导入
from ecommerce import sales
# 导入模块(文件)
sales.calc_tax()
子包 sub-packages
可以在包下面建子包,比如 ecommerce 下建 shopping 子包
对应文件系统,相当于在ecommerce 下新建文件夹shopping,并在shopping文件夹下建 __init__.py文件。
from ecommerce.shopping import sales
# ecommerce.shopping 是子包
# sales 是模块
本地包引用 Intra-package Reference
假设在 ecommerce 文件夹下 customer和shopping文件夹。customer文件夹下有 contact.py文件,shopping文件夹下有sales.py文件。
现在sales.py 中的代码要调用 customer下的 contact。
from ecommerce.customer import contact
# 绝对路径方式
from ..customer import contact
# 双冒号 .. 表示父级,这是相对路径方式
绝对路径和相对路径都可以,但一般还是建议使用绝对路径方式。
dir()函数
dir()函数可以用于取得模块里所有函数的列表和属性的列表
from ecommerce.shopping import sales
print(dir(sales))
# 可以看到很多魔术属性
# [‘__builtins__’, ‘__cached__’, ‘__doc__’, ‘__file__’, ‘__loader__’, ‘__name__’, ‘__package__’, ‘__spec__’]
# 然后我们可以查看下
print(sales.__name__)
print(sales.__package__)
print(sales.__file__)
将模块用为脚本运行
当我们导入某个模块,在调用import时实际已执行一次,然后存在内存里。如果该模块有执行语句的话,就会执行。
包Package(文件夹)里的 __init__.py里如果有可执行代码,也会在导入时执行
我们试一下:
- 在sales.py添加一行执行语句。print(“sales initial in “, __name__)# 前面讲dir函数时说过,每个模块都有一些魔术属性,其中 __name__ 在导入时会显示完整模块的名字。# 如果sales.py作为主程序运行,__name__将显示 “__main__”
- 在ecommerce包里的 __init__.py添加一行执行语句:print(“welcome to ecommerce package.”)
回到app.py,添加导入sales模块语句。
from ecommerce.shopping import sales
运行程序,发现模块里和__init__.py里的可执行语句确实执行了。输出是
“
welcome to ecommerce package.
sales initial in ecommerce.shopping.sales
”
sales模块是导入的,所以执行看到 __name__是具体完整的模块名
如果我们希望sales模块的代码仅在作为主程序运行时才执行,导入模块则不执行的话,可以通过判断 __name__来实现。
sales.py添加if语句。
if __name__ == ‘__main__’:
print(“sales started.”)
calc_tax()
小结
本文介绍了模块和包、子包的使用。
下一篇计划介绍python的标准库。