笔记带有个人侧重点,不追求面面俱到。
16 模块(具体不懂)
出处: 菜鸟教程 - Python3 模块
模块 是一个包含所有你定义的函数和变量的文件,其后缀名是.py。模块可以被别的程序引入,以使用该模块中的函数等功能。
16.1 import 语句
不管执行了多少次 import,一个模块只会被导入一次。
使用 import 语句的时候,Python 解释器会从搜索路径中依次寻找所引入的模块。搜索路径可以通过 sys 模块中的 path 变量进行查看。
>>> import sys
>>> sys.path
['', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages']
>>>
sys.path 输出是一个列表,其中第一项是空串 ‘’,代表当前目录(若是从一个脚本中打印出来的话,可以更清楚地看出是哪个目录),亦即我们执行python解释器的目录(对于脚本的话就是运行的脚本所在的目录)。
不要使用
from package import *
。
推荐使用import package
和from package import item
。
16.2 深入模块
模块除了方法定义,还可以包括可执行的代码。这些代码一般用来初始化这个模块。这些代码只有在第一次被导入时才会被执行。
每个模块有各自独立的符号表,在模块内部为所有的函数当作全局符号表来使用。所以,模块的作者可以放心大胆的在模块内部使用这些全局变量,而不用担心把其他用户的全局变量搞混。从另一个方面,当你确实知道你在做什么的话,你也可以通过 modname.itemname
这样的表示法来访问模块内的函数。
16.3 __name__属性
一个模块被另一个程序第一次引入时,其主程序将运行。 如果我们想在模块被引入时,模块中的某一程序块不执行,可以用 __name__
属性来使该程序块仅在该模块自身运行时执行。每个模块都有一个 __name__
属性,当其值是 __main__
时,表明该模块自身在运行,否则是被引入。
#!/usr/bin/python3
# Filename: using_name.py
if __name__ == '__main__':
print('程序自身在运行')
else:
print('我来自另一模块')
输出:
>>> python using_name.py
程序自身在运行
>>> import using_name
我来自另一模块
16.4 dir() 函数
内置的函数 dir()
可以找到模块内定义的所有名称。以一个字符串列表的形式返回。
>>> a = 1
>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'a']
>>> import sys
>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'a', 'sys']
>>> dir(sys)
['__breakpointhook__', '__displayhook__', '__doc__', '__excepthook__', '__interactivehook__', '__loader__',
'__name__', '__package__', '__spec__', '__stderr__', '__stdin__', '__stdout__', '__unraisablehook__',
'_base_executable', '_clear_type_cache', '_current_exceptions', '_current_frames', '_deactivate_opcache',
'_debugmallocstats', '_enablelegacywindowsfsencoding', '_framework', '_getframe', '_git', '_home', '_xoptions',
'addaudithook', 'api_version', 'argv', 'audit', 'base_exec_prefix', 'base_prefix', 'breakpointhook',
'builtin_module_names', 'byteorder', 'call_tracing', 'copyright', 'displayhook', 'dllhandle',
'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info',
'float_repr_style', 'get_asyncgen_hooks', 'get_coroutine_origin_tracking_depth', 'get_int_max_str_digits',
'getallocatedblocks', 'getdefaultencoding', 'getfilesystemencodeerrors', 'getfilesystemencoding', 'getprofile',
'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettrace', 'getwindowsversion',
'hash_info', 'hexversion', 'implementation', 'int_info', 'intern', 'is_finalizing', 'maxsize', 'maxunicode',
'meta_path', 'modules', 'orig_argv', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'platlibdir',
'prefix', 'ps1', 'ps2', 'pycache_prefix', 'set_asyncgen_hooks', 'set_coroutine_origin_tracking_depth',
'set_int_max_str_digits', 'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr', 'stdin',
'stdlib_module_names', 'stdout', 'thread_info', 'unraisablehook', 'version', 'version_info', 'warnoptions', 'winver']
16.5 包
包 是一种管理 Python 模块命名空间的形式,采用 “点模块名称”。比如一个模块的名称是 A.B, 那么他表示一个包 A中的子模块 B 。
这里给出了一种可能的包结构(在分层的文件系统中):
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
...
在导入一个包的时候,Python 会根据 sys.path 中的目录来寻找这个包中包含的子目录。
目录只有包含一个叫做 __init__.py
的文件才会被认作是一个包,主要是为了避免一些滥俗的名字(比如叫做 string)不小心的影响搜索路径中的有效模块。
# 导入方式
import sound.effects.echo
# 调用方式
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
# 导入方式
import sound.effects import echo
# 调用方式
echo.echofilter(input, output, delay=0.7, atten=4)
# 导入方式
from sound.effects.echo import echofilter
# 调用方式
echofilter(input, output, delay=0.7, atten=4)
当使用 from package import item
这种形式的时候,import 语法会首先把 item 当作一个包定义的名称,如果没找到,再试图按照一个模块去导入。如果还没找到,抛出一个 :exc:ImportError
异常。
反之,如果使用形如 import item.subitem.subsubitem
这种导入形式,除了最后一项,都必须是包,而最后一项则可以是模块或者是包,但是不可以是类,函数或者变量的名字。
16.6 从一个包中导入*
如果包定义文件 __init__.py
存在一个叫做 __all__
的列表变量,那么在使用 from package import *
的时候就把这个列表中的所有名字作为包内容导入。
__all__ = ["echo", "surround", "reverse"]
如果 __all__
真的没有定义,那么使用 from sound.effects import *
这种语法的时候,就不会导入包 sound.effects 里的任何子模块。他只是把包 sound.effects 和它里面定义的所有内容导入进来(可能运行 __init__.py
里定义的初始化代码)。文章来源:https://www.toymoban.com/news/detail-699711.html
扩展阅读: CSDN Python 入门技能树-预备知识-模块管理文章来源地址https://www.toymoban.com/news/detail-699711.html
到了这里,关于菜鸟教程《Python 3 教程》笔记(16):模块的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!