Python3 模块
程序员文章站
2022-06-12 22:46:16
...
文章目录
一、基本定义
- 模块是把一些 定义存放 在文件中,为一些脚本或者交互式的解释器实例使用
- 模块是一个 包含所有定义的函数和变量的文件 ,其后缀名是
.py
- 模块可以 被别的程序引入 ,以使用该模块中的函数等功能
二、import 语句
- 当解释器遇到
import
语句,模块在当前的搜索路径就会 被导入 - 搜索路径 是一个解释器会先进行搜索的所有目录的列表
# 一般形式
import module1, module2, ..., moduleN
# 该实例演示创建模块和导入模块
# 创建 fibo.py 斐波那契(fibonacci)数列模块
def fib(n):
a, b = 0, 1
while b < n:
print(b, end=" ")
a, b = b, a + b
print("")
def fib2(n):
result = []
a, b = 0, 1
while b < n:
result.append(b)
a, b = b, a + b
return result
# 导入 fibo.py 斐波那契(fibonacci)数列模块
>>> import fibo
>>> fibo.fib(1000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fibo.__name__
'fibo'
二、from … import 语句
- 从模块中导入一个 指定的部分 到当前命名空间中
# 一般形式
from modname import name1, name2, ..., nameN
# 这个声明不会把整个 fibo 模块导入到当前的命名空间中,它只会将模块里的 fib 函数引入进来
>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
三、from … import * 语句
- 从一个模块的 所有内容全都导入 到当前的命名空间也是可行的,
- 然而这种声明 不该被过多地使用 ,因为那些由单一下划线
_
开头的名字 不在此例 - 大多数情况,
Python
程序员 不使用 这种方法,因为引入的其它来源的命名,很可能覆盖 已有的定义
# 一般形式
from modname import *
四、__name__属性
- 一个模块被另一个程序 第一次引入时 ,其主程序将运行
- 也可以在模块 被引入时 ,控制模块中的某一程序块不执行
# 创建 using_name.py
if __name__ == '__main__':
print('程序自身在运行')
else:
print('我来自另一模块')
$ python using_name.py
程序自身在运行
>>> import using_name
我来自另一模块
五、dir() 函数
- 可以找到模块内定义的 所有名称
# 简单实例
>>> import keyword
>>> dir(keyword)
['__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'iskeyword', 'kwlist', 'main']
# 如果没有给定参数,就会罗列出当前定义的所有名称
>>> a = [1, 2, 3, 4, 5]
>>> import fibo
>>> fib = fibo.fib
>>> dir() # 得到一个当前模块中定义的属性列表
['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']
>>> a = 5 # 建立一个新的变量 'a'
>>> dir()
['__builtins__', '__doc__', '__name__', 'a', 'sys']
>>>
>>> del a # 删除变量名 'a'
>>>
>>> dir()
['__builtins__', '__doc__', '__name__', 'sys']
六、标准模块
七、包
- 一种管理
Python
模块命名空间的形式,采用 点模块名称,不用担心 不同库之间的模块重名的情况 - 在导入一个包的时候,
Python 3.x
会根据sys.path
中的目录来寻找当前包里所包含的子目录 - 目录只有包含一个叫做
__init__.py
的文件才会被认作是一个包,主要是为了 避免一些滥俗的名字 影响搜索路径中的有效模块 - 最简单的情况,放一个空的
:file:__init__.py
,当然这个文件中也可以包含一些初始化代码或者为__all__
变量赋值
# 该实例演示一种可能的包结构(在分层的文件系统中)
sound/ 顶层包
__init__.py 初始化 sound 包
formats/ 文件格式转换子包
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ 声音效果子包
__init__.py
echo.py
surround.py
reverse.py
...
filters/ filters 子包
__init__.py
equalizer.py
vocoder.py
karaoke.py
...
# 用户可以每次只导入一个包里面的特定模块
import sound.effects.echo
# 以上必须使用全名去访问被导入的子模块
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
# 另一种导入子模块的方法
from sound.effects import echo
# 不需要冗长的前缀导入子模块
echo.echofilter(input, output, delay=0.7, atten=4)
# 直接导入子模块的一个函数或者变量
from sound.effects.echo import echofilter
# 导入子模块,可以直接使用他的 echofilter() 函数
echofilter(input, output, delay=0.7, atten=4)
Explain:
- 当使用
from package import item
形式,item
既可以是包里面的子模块(子包),或者包里面定义的其他名称,比如函数,类或者变量 - 当使用
import item.subitem.subsubitem
形式,subsubitem
既可以是模块或者是包,但是不可以是类,函数或者变量的名字,其他项都必须是包
七、从一个包中导入 *
- 在
Python 3.x
中,会进入文件系统,找到这个包里面所有的子模块,一个一个 的把它们都导入进来 - 这个方法在
Windows
平台上工作的就不是非常好,因为这是一个 大小写不区分 的系统,无法精确导入模块 - 为了解决这个问题,只能创建一个精确的包的索引 ,在定义文件
__init__.py
存在一个叫做__all__
的列表变量,在使用from package import *
的时候就把这个列表中的 所有名字作为包内容导入 - 可别忘了在更新包之后 保证
__all__
也更新
# 在 :file:sounds/effects/__init__.py 变量赋值
__all__ = ["echo", "surround", "reverse"]
Explain:
- 并不主张使用
from package import *
这种方法来导入模块,因为这种方法经常会导致代码的 可读性降低 - 推荐使用
from package import specific_submodule
,除非是你要导入的子模块有可能和其他包的子模块重名,必须使用 绝对路径 来导入特定模块 - 无论是隐式的还是显式的相对导入都是 从当前模块开始的
- 主模块的名字永远是
__main__
,一个Python
应用程序的主模块,应当总是使用 绝对路径 引用 - 包还提供一个额外的目录列表属性
__path__
,里面每一个包含的目录 都有 为这个包服务的__init__.py
,可以修改这个变量,用来影响包含在包里面的模块和子包,这个功能并不常用,一般用来 扩展 包里面的模块