Python 模块搞懂Python模块的用法
在前面的几个章节中我们脚本上是用 python 解释器来编程,如果你从 Python 解释器退出再进入,那么你定义的所有的方法和变量就都消失了。为此 Python 提供了一个办法,把这些定义存放在文件中,为一些脚本或者交互式的解释器实例使用,这个文件被称为模块。
模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py。模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用 python 标准库的方法。下面是一个使用 python 标准库中模块的例子。
1、import sys 引入 python 标准库中的 sys.py 模块。
2、sys.argv 是一个包含命令行参数的列表。
3、sys.path 包含了一个 Python 解释器自动查找所需模块的路径的列表。
importsys
print('命令行参数如下:')
for i in sys.argv:
print(i)
print('\n\nPython 路径为:', sys.path, '\n')
执行结果:
命令行参数如下:
exec.py
Python 路径为: ['/root', '/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']
import 语句
想使用 Python 源文件,只需在另一个源文件里执行 import 语句,语法有两种形式:
1、使用以下语法格式的 import 语句,指定模块中的所有成员,当使用该模块时,需要用别名作为前缀。
import模块名1 [as 别名1], 模块名2 [as 别名2],...:
2、使用from...import语法格式,只导入模块中指定的成员,而不是全部成员。同时无需附加任何前缀,直接使用成员名即可。
from模块名 import 成员名1 [as 别名1],成员名2 [as 别名2],...:
import 语句
[]中的部分可以使用,也可以省略,下面程序使用导入整个模块的最简单语法来导入指定模块:
# 导入sys整个模块
import sys
# 使用sys模块名作为前缀来访问模块中的成员
print(sys.argv[0])
执行结果:
/Users/yf/workspace/python/class/script.py
也可以一次导入多个模块,多个模块之间用逗号隔开。例如如下程序:
# 导入sys、os两个模块
import sys,os
# 使用模块名作为前缀来访问模块中的成员
print(sys.argv[0])
# os模块的sep变量代表平台上的路径分隔符
print(os.sep)
执行结果:
/Users/yf/workspace/python/class/script.py
\
在导入多个模块的同时,也可以为模块指定别名,例如如下程序:
# 导入sys、os两个模块,并为sys指定别名s,为os指定别名o
import sys as s,os as o
# 使用模块别名作为前缀来访问模块中的成员
print(s.argv[0])
print(o.sep)
执行结果:
/Users/yf/workspace/python/class/script.py
\
from … import 语句
下面使用 from...import 的语法来导入指定成员:
# 导入sys模块的argv成员
from sys import argv
# 使用导入成员的语法,直接使用成员名访问
print(argv[0])
执行结果:
/Users/yf/workspace/python/class/script.py
同时,在导入模块成员时,也可以为成员指定别名,具体操作如下:
# 导入sys模块的argv成员,并为其指定别名v
from sys import argv as a
# 使用导入成员(并指定别名)的语法,直接使用成员的别名访问
print(a[0])
执行结果:
/Users/yf/workspace/python/class/script.py
form...import 导入模块成员时,也可以一次性导入多个成员,具体如下:
# 导入sys模块的argv,winver成员
from sys import argv, version
# 使用导入成员的语法,直接使用成员名访问
print(argv[0])
print(version)
执行结果:
/Users/yf/workspace/python/class/script.py
3.8.3 (v3.8.3:6f8c8320e9, May 13 2020, 16:29:34) [Clang 6.0 (clang-600.0.57)]
一次导入多个模块成员时,也可指定别名,同样使用 as 关键字为成员指定别名,例如如下程序::
# 导入sys模块的argv,winver成员
from sys import argv as a, version as v
# 使用导入成员(并指定别名)的语法,直接使用成员的别名访问
print(a[0])
print(v)
执行结果:
/Users/yf/workspace/python/class/script.py
3.8.3 (v3.8.3:6f8c8320e9, May 13 2020, 16:29:34) [Clang 6.0 (clang-600.0.57)]
在使用 from...import 语法时,不推荐使用 from import 导入模块所有成员,例如如下程序
一次导入多个模块成员时,也可指定别名,同样使用 as 关键字为成员指定别名,例如如下程序::
# 导入sys模块的argv,winver成员
from sys import *
# 使用导入成员的语法,直接使用成员名访问
print(argv[0])
print(version)
执行结果:
/Users/yf/workspace/python/class/script.py
3.8.3 (v3.8.3:6f8c8320e9, May 13 2020, 16:29:34) [Clang 6.0 (clang-600.0.57)]
注意:使用from ... import语法导入指定模块内的所有成员,若不同模块内部有相同成员时,程序有出错风险。
若模块有相同的成员,调用模块程序可使用如下代码:
# 导入module1 中的stringutils 成员,并指定其别名为v1
from module1 import stringutils as v1
# 导入module2 中的stringutils 成员,并指定其别名为v2
from module2 import stringutils as v2
v1.text()
v2.text()
__name__属性
一个模块被另一个程序第一次引入时,其主程序将运行。如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用__name__属性来使该程序块仅在该模块自身运行时执行。
if __name__ == '__main__':
print(程序自身在运行)
else:
print(我来自另一模块)
dir() 函数
内置的函数 dir() 可以找到模块内定义的所有名称。以一个字符串列表的形式返回。
# 导入sys模块的argv,winver成员
import sys
print(dir(sys))
执行结果:
['__breakpointhook__', '__displayhook__', '__doc__', '__excepthook__', '__interactivehook__', '__loader__', '__name__', '__package__', '__spec__', '__stderr__', '__stdin__', '__stdout__', '__unraisablehook__', '_base_executable', '_clear_type_cache', '_current_frames', '_debugmallocstats', '_framework', '_getframe', '_git', '_home', '_xoptions', 'abiflags', 'addaudithook', 'api_version', 'argv', 'audit', 'base_exec_prefix', 'base_prefix', 'breakpointhook', 'builtin_module_names', 'byteorder', 'call_tracing', 'callstats', 'copyright', 'displayhook', 'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info', 'float_repr_style', 'get_asyncgen_hooks', 'get_coroutine_origin_tracking_depth', 'getallocatedblocks', 'getcheckinterval', 'getdefaultencoding', 'getdlopenflags', 'getfilesystemencodeerrors', 'getfilesystemencoding', 'getprofile', 'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info', 'intern', 'is_finalizing', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'pycache_prefix', 'set_asyncgen_hooks', 'set_coroutine_origin_tracking_depth', 'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout', 'thread_info', 'unraisablehook', 'version', 'version_info', 'warnoptions']
注意:如果没有给定参数,那么 dir() 函数会罗列出当前定义的所有名称:
包的创建
包其实就是文件夹,更确切的说,是一个包含“__init__.py”文件的文件夹。因此,如果我们想手动创建一个包,只需进行以下 2 步操作:
新建一个文件夹,文件夹的名称就是新建包的包名;
在该文件夹中,创建一个 __init__.py 文件(前后各有 2 个下划线‘_’),该文件中可以不编写任何代码。
例如,现在我们创建一个非常简单的包,该包的名称为 tools,可以仿照以上 2 步进行:
第一创建一个文件夹,其名称设置为 tools,第二在该文件夹中添加一个 __init__.py 文件,此文件中可以不编写任何代码。不过,这里向该文件编写如下代码:
print(hello world!)
可以看到,__init__.py 文件中,包含了 2 部分信息,分别是此包的说明信息和一条 print 输出语句。由此,我们就成功创建好了一个 Python包。创建好包之后,我们就可以向包中添加模块。
包的导入
通过前面的学习我们知道,包其实本质上还是模块,因此导入模块的语法同样也适用于导入包。导入方法可归结为以下 3 种:
import 包名[.模块名 [as 别名]]
from 包名 import 模块名 [as 别名]
from 包名.模块名 import 成员名 [as 别名]
用 [] 括起来的部分,是可选部分,即可以使用,也可以直接忽略。
1、import 包名[.模块名 [as 别名]]
import tools.module1
tools.module1.show("hello world!")
通过此语法格式导入包中的指定模块后,在使用该模块中的成员(变量、函数、类)时,需添加“包名.模块名”为前缀。
2、from 包名 import 模块名 [as 别名]
from tools import module1
module1.show("hello world!")
使用此语法格式导入包中模块后,在使用其成员时不需要带包名前缀,但需要带模块名前缀。
3、from 包名.模块名 import 成员名 [as 别名]
通过该方式导入的变量(函数、类),在使用时可以直接使用变量名(函数名、类名)调用。
from tools.module1 import show
show("hello world!")
使用此语法格式导入包中模块后,在使用其成员时不需要带包名前缀,但需要带模块名前缀。