python 模块

1. 定义:

  • python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 python 对象定义和Python语句。模块就是python程序。
  • python提供了强大的模块支持,主要体现在,不仅 Python 标准库中包含了大量的模块(称为标准模块),还有大量的第三方模块,开发者自己也可以开发自定义模块。通过这些强大的模块可以极大地提高开发者的开发效率。

下例是个简单的模块 study.py

#!/usr/bin/env python3
# --*-- coding=utf-8 --*--

def print_func(varible):
    print('print: ', varible)
    return

print_func('hello') # ('print: ', 'hello')

(1)容器,如列表、字符串、字典等,它们都是对数据的封装;
(2)函数是对 Python 代码的封装;
(3)类是对方法和属性的封装,也可以说是对函数和数据的封装。
(4)模块,可以理解为是对代码更高级的封装,即把能够实现某一特定功能的代码编写在同一个 .py 文件中,并将其作为一个独立的模块,这样既可以方便其它程序或脚本导入并使用,同时还能有效避免函数名和变量名发生冲突。

2. 模块的引入:import 语句

模块定义好后,我们可以使用 import 语句来引入模块,主要有以下两种:
(1)import: 会导入指定模块中的所有成员(包括变量、函数、类等)

import 模块名1 [as 别名1], 模块名2 [as 别名2], …
# 用[]括起来的部分,可以使用,也可以不用

当需要使用模块中的成员时,需用该模块名(或别名)作为前缀,否则python解释器会报错。
例如要引用模块 math,在文件最开始的地方用 import math 来引入。调用 math 模块中的函数时,必须这样引用:

模块名.函数名

当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入。一个模块只会被导入一次,不管执行了多少次import。

#!/usr/bin/env python3
# --*-- coding=utf-8 --*--

# 导入模块
import study

# 现在可以调用模块里包含的函数了
study.print_func("test")

(2)from…import 语句:从模块中导入一个指定的部分到当前命名空间中
语法如下:

from 模块名 import 成员名1 [as 别名1], 成员名2 [as 别名2], …
# 用[]括起来的部分,可以使用,也可以不用

例如:要导入模块study的print_func函数,使用如下语句:

from study import print_func

这种语法格式的 import 语句,只会导入模块中指定的成员,而不是全部成员。使用该成员时,无需附加任何前缀,直接使用成员名(或别名)即可。

from…import* 语句
把一个模块的所有内容全都导入到当前的命名空间也是可行的,只需使用如下声明:

from 模块名 import *

不推荐使用“from 模块 import”这种语法导入指定模块内的所有成员,因为它存在潜在的风险, 比如同时导入模块1和模块2内的所有成员,假如这两个模块内都有相同的函数,调用时就会混乱。

3. 自定义模块问题

直接向模块程序中添加测试代码,会导致一个问题,即当其它程序导入该模块时,其中的测试函数会自动执行。例如,在 study.py 同目录下,再创建一个新的study2.py 文件

study.py

#!/usr/bin/env python3
# --*-- coding=utf-8 --*--

def print_func(varible):
    print('print: ', varible)
    return

print_func('hello') # ('print: ', 'hello')

study2.py

#!/usr/bin/env python3
# --*-- coding=utf-8 --*--

# 导入模块
import study

结果:(‘print: ', ‘hello’)
这显然不是期望看到的结果。希望的效果是:直接运行模块文件(相当于测试文件),程序会执行该模块的测试函数;如果是其他程序导入该模块,程序不应该执行该模块的测试函数。

   要实现这个效果,需要内置的 name 变量。直接运行一个模块时,name 变量的值为 main;而将模块被导入其他程序中并运行该程序时,处于模块中的 name 变量的值就变成了模块名。因此,如果希望测试函数只有在直接运行模块文件时才执行,则在调用测试函数时增加判断,即只有当 name ==‘main’ 时才调用测试函数。

#!/usr/bin/env python3
# --*-- coding=utf-8 --*--

def print_func(varible):
    print('print: ', varible)
    return

if __name__ =='__main__':
    print_func('hello') # ('print: ', 'hello')

4. python导入模块的搜索路径

import导入模块后,会按照以下顺序查找指定的模块文件:

  • 1、当前目录,即当前执行的程序文件所在目录下查找;
  • 2、如果不在当前目录,到 PYTHONPATH(环境变量)下的每个目录中查找;
  • 3、如果都找不到,到 python 默认的安装目录下查找,UNIX下,默认路径一般为/usr/local/lib/python/。
       以上所有涉及到的目录,都保存在标准模块 sys 的 sys.path 变量中,通过此变量,可以输出指定程序文件支持查找的所有目录。因此,如果要导入的模块没有存储在 sys.path 显示的目录中,那么导入该模块并运行程序时,Python 解释器会抛出 ModuleNotFoundError(未找到模块)异常。

为了让python 能找到自定义(或第三方提供) 的模块,可以用以下 3 种方式来告诉它:
① 向 sys.path 中临时添加模块文件存储位置的完整路径;

import sys
sys.path.append('D:\\python_module')

② 将模块放在 sys.path 变量中已包含的模块加载路径中。
③ 设置系统环境变量。

5.__all__变量用法

   在默认情况下,如果使用“from 模块名 import *”这样的语句来导入模块,程序会导入该模块中所有不以下划线开头的成员(包括变量、函数和类)。但在一些场景中,我们并不希望每个成员都被暴露出来供外界使用,此时可借助于模块的 all 变量,将变量的值设置成一个列表,只有该列表中的成员才会被暴露出来。
study.py

#!/usr/bin/env python3
# --*-- coding=utf-8 --*--

'''测试__all__变量的模块'''
def print_func(varible):
    print('print_func: ', varible)
def print_func1():
    print("print_func1")
def print_func2():
    print('print_func2')
# 定义__all__变量,指定默认只导入print_func1和print_func2两个成员
__all__ = ['print_func1', 'print_func2']
if __name__ =='__main__':
    print_func('hello') # ('print: ', 'hello')

test.py

#!/usr/bin/env python3
# --*-- coding=utf-8 --*--

from study import *
# print_func('hello') # NameError: name 'print_func' is not defined
print_func1()
print_func2()

如果想要使用模块内 all 列表之外的成员,有两种解决方法:

  • 第一种使用“import 模块名”来导入模块。
  • 第二种是使用“from 模块名 import 成员”来导入指定成员。在这种方式下,即使想导入的成员没有位于 all 列表中,也依然可以导入。

python 包:使用模块可以有效避免变量名或函数名重名引发的冲突,如果模块名重复怎么办呢?因此,python提出了包的概念。包就是文件夹,在该文件夹下必须存在一个名为“init.py” 的文件。
python 库:相比模块和包,库是一个更大的概念,例如在 Python 标准库中的每个库都有好多个包,而每个包中都有若干个模块

6. 包的使用

创建一个包,主要分为如下两步:

  1. 创建一个文件夹,该文件夹的名字就是该包的包名。
  2. 在该文件夹内创建一个名为 init.py 的python文件,在此文件中,可以不编写任何代码,也可以编写一些python初始化代码,在此文件中编写的代码,其他程序文件导入包时,会自动执行。

包的本质就是模块,导入方法可归结为以下 3 种。
① import 包名[.模块名 [as 别名]]

import pypackage.study
pypackage.study.print_func(100)

② from 包名 import 模块名 [as 别名]

from pypackage import study
study.print_func(100)

③ from 包名.模块名 import 成员名 [as 别名]

from pypackage.study import print_func
print_func(100)

用 [] 括起来的部分,是可选部分,即在使用时可以忽略。

init.py 文件的主要作用是导入该包内的其他模块。
通过在 init.py 文件使用import语句将必要的模块导入,这样当向其他程序中导入此包时,就可以直接导入包名,也就是使用import 包名(或from包名import *)的形式即可。

下载和安装第三方模块,可以使用 Python 提供的 pip 命令实现。pip 命令的语法格式如下:

pip install|uninstall|list 模块名
  1. install:用于安装第三方模块,当 pip 使用 install 作为参数时,后面的模块名不能省略。
  2. uninstall:用于卸载已经安装的第三方模块,选择 uninstall 作为参数时,后面的模块名也不能省略。
  3. list:用于显示已经安装的第三方模块。
    如果想要查看已经安装的第三方模块,可以在使用如下命令:
pip list

7. 命名空间和作用域

   如果一个局部变量和一个全局变量重名,则局部变量会覆盖全局变量。   python会智能地猜测一个变量是局部的还是全局的,它假设任何在函数内赋值的变量都是局部的。
   因此,如果要给函数内的全局变量赋值,必须使用 global 语句。global VarName 的表达式会告诉 python, VarName 是一个全局变量,这样 python 就不会在局部命名空间里寻找这个变量了。

例如,在全局命名空间里定义一个变量m。在函数内给m赋值,然后python 会假定m是一个局部变量。然而,我们并没有在访问前声明一个局部变量m,结果就是会出现一个UnboundLocalError的错误。取消注释# global m就可以解决这个问题

#!/usr/bin/env python3
# --*-- coding=utf-8 --*--

m = 1
def AddMoney():
   # 想改正代码就取消以下注释:
   # global m
   m = m + 1

print m
AddMoney()
print m

dir()函数:返回一个排好序的字符串列表,容纳了在一个模块里定义的所有模块,变量和函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值