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!")

使用此语法格式导入包中模块后,在使用其成员时不需要带包名前缀,但需要带模块名前缀。