目录

一、模块的基本用法

一、导入模块

二、编写一个模块

二、在哪里查找模块

三、是否需要编译模块

四、模块也可独立运行

五、如何查看模块提供的函数名


Python中的模块实际上就是包含函数或者类的 Python 脚本。对于一个大型脚本而言,经常需要将其功能细化,将实现不同功能的代码放到不同的脚本中实现,在其他的脚本中以模块的形式使用细化的功能,以便于脚本的维护与重用。

一、模块的基本用法

模块是包含函数和其他语句的 Python 脚本文件,它以 ".py" 为后缀名,也就是 Python 脚本的后缀名。用做模块的 Python 脚本与其他脚本并没有什么区别。

在 Python 中可以通过导入模块,然后使用模块中提供的函数或者数据。

一、导入模块

在 Python 中可以使用以下两种方法导入模块或者模块中的函数。

  • import  模块名
  • import  模块名  as  新名字
  • from  模块名  import  函数名

其中,使用 import 是将整个模块导入,而使用 from 则是将模块中某一个函数或者名字导入,而不是整个模块。使用 import 和 from 导入模块还有一个不同:要想使用 import 导入模块中的函数,则必须以模块名 + "." + 函数名的形式调用函数;而要想使用 from 导入模块中的函数,则可以直接使用函数名调用,不必在前面加上模块名称。

>>> import math  # 使用 import 导入 math 模块
>>> math.sqrt(9)  # 使用 math 模块中的 sqrt 函数
3.0
>>> sqrt(9)  # 直接使用 sqrt 名字调用函数——发生错误
Traceback (most recent call last):File "<stdin>", line 1, in <module>
NameError: name 'sqrt' is not defined
>>> from math import sqrt  # 使用 from 导入 math 模块中的 sqrt 函数
>>> sqrt(9)  # # 直接使用 sqrt 名字调用函数——成功使用
3.0

使用 from 导入模块中的函数后,使用模块中的函数会方便得多,不用在调用函数时使用模块名。如果要想将模块中所有函数都采用这种方式导入,则可以在 from 中使用 "*" 通配符,表示导入模块中的所有函数。

>>> from math import sqrt  # 仅从 math 模块中导入 sqrt
>>> sqrt(9)
3.0
>>> sin(30)  # 调用 math 模块中的 sin 函数出错
Traceback (most recent call last):File "<stdin>", line 1, in <module>
NameError: name 'sin' is not defined
>>> from math import *  # 重新从 math 模块中导入所有函数
>>> sin(30)  # 重新调用 sin 函数
-0.9880316240928618

在 Python 2.x 中,还可以通过使用内置函数 reload 重新载入模块。reload 可以在模块被修改的情况下不必关闭 Python 而重新载入模块。在使用 reload 重载模块时,该模块必须已经事先被导入。

在 Python 3 中,reload 函数已经被删除,要重新载入模块,则需要使用 importlib(版本旧一点的名称是 imp ) 模块中的 reload 函数。

>>> import os              # 导入 os 模块
>>> import importlib       # 导入 importlib 函数
>>> importlib.reload(os)   # 重新载入 os 模块
<module 'os' from 'C:\\Users\\图图\\AppData\\Local\\Programs\\Python\\Python37-32\\lib\\os.py'>

二、编写一个模块

下面是一个简单的模块,该模块中只包含一个函数。这个函数只打印 "I am a module!"。该模块保存为 mymodule.py。代码如下:

def show():   # 声明 show 函数print('I am a module!')

编写一个调用函数 show 的脚本,将其保存为 usemodule.py。代码如下:

import mymodule    # 导入模块
mymodule.show()    # 调用模块中的 show 函数

脚本运行后输出如下:

除了在模块中声明函数外,还可以在模块中定义变量。模块中的变量同样可以在其他脚本中使用。以下代码在 mymodule.py 模块中添加了一个名为 name 的变量。

def show():print('I am a module!')
name = 'mymodule.py'  # 在模块中添加一个 name 变量

以下代码为修改的 usemodule.py 模块,其中使用了 mymodule.py 中的 name 变量。

import mymodule
mymodule.show()
print(mymodule.name)      # 打印模块中的 name 变量
mymodule.name = 'usemodule.py'   # 将 name 变量重新赋值
print(mymodule.name)

脚本运行后输出如下:

二、在哪里查找模块

编写好的模块只有被 Python 找到才能被导入。上一节中编写的模块和调用模块的脚本位于同一个目录中,因此不需要进行设置就能被 Python 找到并导入。如果在该目录中新建一个 module 目录,并且把 mymodule.py 转移到 module 目录中,再次运行 usemodule.py,则输出如下:

运行脚本出错,Python 解释器没有找到 mymodule.py 模块,在导入模块时,Python 解释器首先在当前目录中查找要导入的模块,如果未找到模块,则 Python 解释器会从 sys 模块中 path 变量指定的目录中查找导入模块。如果在以上所有目录中都未找到导入的模块,则会输出出错信息。

以下代码是使用 sys.path 输出 Python 的模块查找路径。

>>> import sys
>>> sys.path
['D:\\Python',
'D:\\Python',
'C:\\Users\\图图\\AppData\\Local\\Programs\\Python\\Python37-32\\python37.zip',
'C:\\Users\\图图\\AppData\\Local\\Programs\\Python\\Python37-32\\DLLs',
'C:\\Users\\图图\\AppData\\Local\\Programs\\Python\\Python37-32\\lib',
'C:\\Users\\图图\\AppData\\Local\\Programs\\Python\\Python37-32',
'C:\\Users\\图图\\AppData\\Local\\Programs\\Python\\Python37-32\\lib\\site-packages',
'C:\\Program Files\\JetBrains\\PyCharm 2018.3.5\\helpers\\pycharm_matplotlib_backend']

在脚本中可以向 sys.path 添加模块查找路径。以下所示脚本中,将当前目录下的 module 子目录添加到 sys.path 中,并从 module 目录中导入 mymodule.py 模块。代码如下。

import os
import sys
modulepath = os.getcwd() + '\\module'
sys.path.append(modulepath)
print(sys.path)
import mymodule
mymodule.show()
print(mymodule.name)
mymodule.name = 'usenodule.py'
print(mymodule.name)

运行脚本输出如下:

['D:\\Python',
'D:\\Python',
'C:\\Users\\图图\\AppData\\Local\\Programs\\Python\\Python37-32\\python37.zip',
'C:\\Users\\图图\\AppData\\Local\\Programs\\Python\\Python37-32\\DLLs',
'C:\\Users\\图图\\AppData\\Local\\Programs\\Python\\Python37-32\\lib',
'C:\\Users\\图图\\AppData\\Local\\Programs\\Python\\Python37-32',
'C:\\Users\\图图\\AppData\\Local\\Programs\\Python\\Python37-32\\lib\\site-packages',
'C:\\Program Files\\JetBrains\\PyCharm 2018.3.5\\helpers\\pycharm_matplotlib_backend',
'D:\\Python\\module']
I am a module!
mymodule.py
usenodule.py

从输出可以看出,当前路径也被添加到了 sys.path 路径列表中,这说明 Python 其实是按照 sys.path 中的路径来查找模块的。之所以首先在当前目录中查找,那是因为 Python 解释器在运行脚本前将当前目录添加到 sys.path 路径列表中了。

三、是否需要编译模块

在上面的例子中,运行完 usemodule.py 会发现,module 目录中除了 mymodule.py 文件外,还多了一个后缀名为 ".pyc" 文件。其实,该文件就是 Python 将 mymodule.py 编译成字节码的文件。虽然 Python 是脚本语言,但 Python 可以将脚本编译成字节码的形式。对于模块,Python 总是在第一次调用后就将其编译成字节码的形式,以提高脚本的启动速度。

Python 在导入模块时会查找模块的字节码文件,如果存在则将编译后的模块的修改时间同模块的修改时间相比较。如果两者的修改时间不相符,则 Python 将重新编译模块,以保证两者内容相符。被编译的脚本也是可以直接运行的。

当然,没有必要去刻意编译 Python 脚本。不过,由于 Python 是脚本,如果不想将源文件发布,则可以发布编译后的脚本,这样能起到一定的保护源文件的作用。

对于非模块的脚本,Python 不会在运行脚本后将其编译成字节码的形式。如果想将其编译,可以使用 commile 模块。以下代码可以将 usemodule.py 文件编译成 ".pyc" 文件。

import py_compile       # 导入 py_compile 模块
py_compile.compile('usemodule.py','usemodule.pyc')   # 编译 usemodule.py

运行 compile.py 后,可以看到当前目录中多了一个 usemodule.pyc 文件。在 Python 3 中,如果在 py_compile.compile 函数中不指定第 2 个参数,则将在当前目录新建一个名为 "__pycache__" 的目录,并在这个目录中生成 "被编译模块名.cpython-32.pyc" 的 pytc 字节码文件。

运行 usemodule.py 脚本输出如下:

['D:\\Python',
'D:\\Python',
'C:\\Users\\图图\\AppData\\Local\\Programs\\Python\\Python37-32\\python37.zip',
'C:\\Users\\图图\\AppData\\Local\\Programs\\Python\\Python37-32\\DLLs',
'C:\\Users\\图图\\AppData\\Local\\Programs\\Python\\Python37-32\\lib',
'C:\\Users\\图图\\AppData\\Local\\Programs\\Python\\Python37-32',
'C:\\Users\\图图\\AppData\\Local\\Programs\\Python\\Python37-32\\lib\\site-packages',
'C:\\Program Files\\JetBrains\\PyCharm 2018.3.5\\helpers\\pycharm_matplotlib_backend',
'D:\\Python\\module']
I am a module!
mymodule.py
usenodule.py

可以看到其输出与前面的输出一样。编译后生成的 usemodule.pyc 文件并没有改变程序功能,只是以 Python 字节码的形式存在。

另外,还可以通过 Python 的命令行选项将脚本优化编译。Python 编译的优化选项有以下两个:

  • -O      该选项对脚本的优化不多,编译后的脚本以 ".pyo" 为扩展名。凡是以 ".pyo" 为扩展名的 Python 字节码都是经过优化的。

  • -OO   该选项对脚本优化的程度较大。使用该标志可以使编译的 Python 脚本更小。使用该选项可能导致脚本运行错误,因此,因谨慎使用。

可以通过在命令行中输入以下命令将 usemodule.py 优化编译。

python -O compile.py
python -OO compile.py

四、模块也可独立运行

每个 Python 脚本在运行时都有一个 __name__ 属性(name 前后均是两条下划线)。在脚本中通过对 __name__ 属性值的判断,可以让脚本在作为导入模块和独立运行时都可以正确运行。

在 Python 中,如果脚本作为模块被导入,则其 __name__ 属性被设置为模块名;如果脚本独立运行,则其 __name__ 属性被设置为 "__main__"。因此可以通过 __name__ 属性来判断脚本的运行状态。

以下所示脚本 mymodule2.py 既可以独立运行,也可以作为模块被其他脚本导入。

# file: mymodule2.pydef show():print('I am a module!')
if __name__ == '__main__':show()print('I am not a module!')

以下所示脚本 usemodule2.py 可以调用 mymodule2.py 模块

# file: usemodule2.pyimport mymodule2
mymodule2.show()
print('my __name__ is', __name__)

运行 usemodule2.py 后,输出如下:

运行 mymodule2.py 后,输出如下:

五、如何查看模块提供的函数名

如果需要获得导入模块中所有声明的名字、函数等,就可以使用内置的函数 dir() 来进行操作。

以下所示代码将获得 sys 模块中的名字和函数。

import sys
print(dir(sys))

输出结果如下:

['__breakpointhook__', '__displayhook__', '__doc__', '__excepthook__',
'__interactivehook__', '__loader__', '__name__', '__package__', '__spec__',
'__stderr__', '__stdin__', '__stdout__', '_clear_type_cache', '_current_frames',
'_debugmallocstats', '_enablelegacywindowsfsencoding', '_framework', '_getframe',
'_git', '_home', '_xoptions', 'api_version', 'argv', 'base_exec_prefix', 'base_prefix',
'breakpointhook', 'builtin_module_names', 'byteorder', 'call_tracing', 'callstats',
'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_coroutine_wrapper', 'getallocatedblocks', 'getcheckinterval', 'getdefaultencoding',
'getfilesystemencodeerrors', 'getfilesystemencoding', 'getprofile', 'getrecursionlimit',
'getrefcount', 'getsizeof', 'getswitchinterval', 'gettrace', 'getwindowsversion',
'hash_info', 'hexversion', 'implementation', 'int_info', 'intern', 'is_finalizing',
'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks',
'path_importer_cache', 'platform', 'prefix', 'set_asyncgen_hooks',
'set_coroutine_origin_tracking_depth', 'set_coroutine_wrapper', 'setcheckinterval',
'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr', 'stdin',
'stdout', 'thread_info', 'version', 'version_info', 'warnoptions', 'winver']

dir() 函数的原型如下:

dir( [object] )
  • object        可选参数,要列举的模块名。

如果不向 dir() 函数传递参数,那么 dir() 函数将返回当前脚本的所有名字列表。如下所示。

a = [1, 3, 6]  # 定义一个列表
b = 'python'  # 定义一个字符串
print(dir())  # 使用 dir() 函数获得当前脚本所有名字列表def fun():  # 定义一个函数print('python')print(dir())  # 再次使用 dir() 函数

两个 print 的输出结果如下:

初学__Python——Python 可重用结构:Python模块相关推荐

  1. 【Python学习教程】Python变量类型和运算符

    文章目录 Python变量的定义和使用 Python 变量的赋值 Python 变量的使用 Python 是弱类型的语言 Python整数类型(int)详解 关于 Python 2.x 整数的不同进制 ...

  2. 生活不止眼前的苟且,还有python和远方——认识Python

    02--python要点 1.Python语言 1.1 Python语言的基本概念 • Python 是一种极少数能兼具 简单 与 功能强大 的编程语言.你将惊异于发现你正在使用的这门编程语言是如此简 ...

  3. python函数的使用方法图解_零基础python之4函数重用-函数与模块(附详细的步骤和程序)...

    4代码重用--函数与模块 重用代码是构建一个可维护系统的关键. 代码组是Python中对块的叫法. 对之前的vowels代码功能创建一个函数名为search_for_vowels( ) 在函数调用时结 ...

  4. python学习——主要的代码结构,模块和包

    文章目录 前言 一.python的代码结构 1.1注释#与反斜杠\链接 1.2if elif else 1.3while.for.continue.else 1.4zip().range() 1.5列 ...

  5. 初学__Python——Python中文支持、Python计算器

    目录 一.Python对中文的支持 二.简单实用的Python计算器 一.Python对中文的支持 在Python中,可以在各种编码间相互转换. 如果在交互式命令中使用中文,即便不做处理,一般也不会出 ...

  6. 初学__Python——Python代码的组织形式

    目录 一.用缩进来分层 二.代码注释的方式--两种 三.语句的断行 一.用缩进来分层 Python脚本的结构非常清晰,在Python中,使用代码缩进来表示分层. 代码缩进一般用于函数定义.类的定义以及 ...

  7. 初学__Python——Python数据类型之字符串

    目录 一.Python中的字符串 二.字符串中的转义字符 三.操作字符串 四.字符串中的索引与分片 五.格式化字符串 六.字符串.数字类型的转换 七.原始字符串(Raw String) 一.Pytho ...

  8. Python中的类、模块和包究竟是什么?

    Python培训教程:Python中的类.模块和包究竟是什么?在Python和其他编程语言中,都有类似或相同的概念,如对象.类.模块.包,名称都是一样的,只不过会有细微的一些区别,正是因为有这些存在, ...

  9. python 学习笔记8 (模块)

    Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句. 模块让你能够有逻辑地组织你的 Python 代码段. 把相关的代码 ...

最新文章

  1. java 图片传输方式_Java图像传输方法
  2. 依赖版本控制-pom文件介绍
  3. 申请成为qq互联个人开发者步骤(注意事项)2018
  4. 总投资200亿,中国第五座航天发射中心来了!为何选址在宁波?
  5. 在线编程语言模拟(Java,C,Python,R语言,Ruby,PHP,Perl,Go等)
  6. java跟setattribute,java 中的request.setAttribute和session.setAttribute的区别
  7. 计算机领域男的多大年龄退休,2022年后男性几岁退休 2022退休时间表
  8. html5微信分享图标和文本设置,科技常识:Html5 实现微信分享及自定义内容的流程...
  9. 企业对计算机类专业人才培养方案,应用型本科计算机科学与技术专业人才培养方案探讨...
  10. 网络安全·网络入侵检测系统
  11. 本来共享的计算机突然无法访问,win7无法启用共享访问怎么办_win7无法启用共享访问如何处理-win7之家...
  12. Flutter 项目实战 网络请求MD5+时间戳+验证签名 十一
  13. [Tableau] 销售团队绩效分析与相关策略指导
  14. 先吃奶油还是先吃蛋糕--推迟满足感
  15. Deepin系统标题栏及其按钮美化
  16. 红豆角源码--红豆角系统红豆角APP拼团系统源码分享
  17. 怎么获得红米手机4A的Root权限
  18. 行为识别:让机器学会“察言观色”第一步
  19. 特征工程之One-Hot编码、label-encoding、自定义编码
  20. 【量化投资】高频交易(HFT),下一个风口?

热门文章

  1. 数据列过滤条件常用处理
  2. 创建销售订单BAPI一些心得
  3. 13、Power Query-逆透视列的实例(下)
  4. 如何区分“Invoice代码”和“Invoice号码”?
  5. SAP TableControl 控制单个单元格输入
  6. SAP号码段表及相关操作T-CODE
  7. 什么是SAP重复性生产
  8. SAP Business ByDesign云计算ERP软件
  9. ABAP 获取登陆者的IP地址和主机名
  10. HANA全面上市,成为SAP史上用户数量增长最快的产品之一