欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python3 模块

程序员文章站 2022-06-12 22:51:47
...

在Python中模块的后缀为.py文件,它是一个包含所有与该模块相关联的函数与变量的文件,模块可以保存,也可以被其它程序引入,这也是使用Python标准库的方法,在Python的标准安装中包含了一组自带的模块,这些模块被称为标准库

不仅如此,Python的开发者们可以根据需要不断扩充模块,各行各业的Python用户也贡献了大量的Python拓展库,它们大大拓展了Python的功能,这也是Python日益强大的一个不可忽略的原因;

一.如何导入模块:

1.自定义一个模块:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
' a simple try'
__author__ = 'william'

def add(a,b):
    print('两数之和为:%d' % (a+b))

在这个例子中,我写了一个非常简单的add模块,并保存文件格式为 add.py,其中,它的前两行是标准注释,第一行注释可以让这个add模块文件直接在Linux/Unix/Mac上运行,第二行注释表示.py文件本身使用标准UTF-8编码;接下来第三行是为这个模块添加的字符串注解说明,就像在函数里面添加的那个差不多,不管任何模块它的第一行字符串都会被视为注解说明,之后第四行则是这个模块编写者的名字,用__anthor__变量存入;

之后第六行才是模块的主体部分,即一个函数,模块其实封装的就是一个又一个的函数,在这之前的所有工作其实你都可以不做,只要有完整的函数那么这个模块导入之后就可以正常的发挥作用;

模块定义好了之后,就可以导入并使用它了,这里我又创建了一个文件,在该文件内导入add模块:

2.导入模块

import add as a
a.add(3,9)# 两数之和为:12

简单分析一下这两条语句,Python里面用import语句导入模块,注意导入时候import后面跟的是模块名,在导入时你也可以用 as 给该模块指定别名,当然你也可以不指定;执行import语句时,Python会读取add文件并将其中所有的函数都复制到当前程序内,你看不到这些代码,因为在程序运行时,Python在幕后进行这些工作;

现在我已经导入了自定义模块add并通过指定别名获得了变量a,a指向add模块,通过a可以使用里面的所有函数,于是调用add模块里面的add()函数,成功输出;

<小问题>

这里我在实现时其实遇到了一个小问题,也一并分享:

最开始我的导入代码是这样的:

import add as a
print(a.add(3,9))
#然后输出是这样的:
两数之和为:12
None

输出有两行,第一行是我想要的,可第二行莫名其妙地输出了一个None是怎么回事?而且无论我怎么更换数据,更换方法,只要输出就伴随着None出现;
在网上搜了一下,发现原来是print()函数多输出了一次…

其实是这样的,我的add模块里面的add()函数没有返回值,函数没有返回值Python默认返回None,而又因为我的add()函数里面本就有print语句,而我在调用时又用了print,相当于输出了两次,第一次输出了正常结果,第二次输出的是add()函数的返回值None;

3.import的多种语法

以导入sys模块为例,sys模块负责Python解释器与程序的交互,并且提供了一系列的函数和变量,用于操作Python运行时的环境;现在来导入它:

导入特定函数:

from sys import argv #导入sys模块的argv成员
from sys import argv as a #导入argv并指定别名a

这种导入方法导入的函数可以直接用,不需要使用句点;

导入模块所有函数:

from sys import *

这种导入方法并不推荐,尤其是在使用并非自己编写的大型模块时;

另外注意,一个模块只会被导入一次,不管你执行了多少次import,这样可以防止导入模块重复执行;

4.一个例子

自定义一个简单模块,文件名为mess,如下:

#mess.py
print('hello,world')
def hello():
    print('hello,python')

接着我们导入它:

import mess as m
m.hello()
#运行结果:
hello,world
hello,python

接着我们只导入hello函数再试一次:

from mess import hello
hello()
#运行结果:
hello,world
hello,python

应该已经发现了,无论是导入整个模块,还是只导入特定函数,模块内的第一行print语句总被执行,这说明哪怕是在导入特定函数时,Python依然会加载并执行模块中的所有代码;

其实,导入模块的本质就是把该模块的所有代码全部加载到内存并执行,然后制定一个变量,如果导入的是整个模块,那么这个变量就是module型,而在模块中定义的所有程序单元都相当于该module对象的成员,如果导入的是指定函数,那么就会只导入指定变量、函数等成员,并不导入整个模块;

5.__name__属性

每个模块都有一个__name__属性,当模块未被导入时,它的值是__main__,否则则表明模块已被导入;
例:

if __name__ == '__main__':
    print('hello,world')
else:
     print('hello,python')
 
 #在自身文件内运行:
 hello,world
 
 #导入后:
 import mess
 hello,python

6.__all__变量用法

如果采用 from module import * 这种用法来导入模块的话,通常会导入模块内所有成员单位,但如果该模块定义了__all__变量,那么这种方法就只能导入__all__规定可以导出的成员单位,定义__all__时用定义列表的方法即
all = [] 来划分成员单位,在这个列表之内的成员都可以被导出,但之外的就无法被导出,也无法被使用;

但如果确实想使用__all__规定之外的成员也可以,不用这种 * 导入法就ok:

import module
from module import 成员

以上两种总可以导入__all__规定之外的成员;

二.包

1.什么是包

为了更好的管理多个模块源文件,Python提供了包的概念,包其实就是一个文件夹,这个文件夹里面存放了很多模块,除此之外还有一个__init__.py文件,包的本质依然是模块,因此包也可以包含子包;

Python采用“点模块名称”来使用包中的模块,这样也可以避免不同的包之间重名的情况,比如,A.B就表示A包下的B模块;导入包的方法与导入模块一样;

2.创建一个包

一个包里面必须包含一个 init.py 文件,下面来创建一个包:
首先我们创建一个文件夹,文件夹的名字就是包的名字,然后在该文件夹内创建一个__init__.py文件,之后就可以编写包内的模块了,这里我创建了一个f_package的包;

#add.py
def add(a,b):
    print('两数之和为%d' % (a+b))

#sub.py   
def sub(a,b):
    print('两数之差为%d' % (a-b))
 
#mul.py  
def mul(a,b):
    print('两数相乘为%d' % (a*b))

#div.py
def d,iv(a,b):
    if b == 0:
        print('error')
    else:
        print('两数相除为%d' % (a/b))

f_package里面有5个文件,除却__init__.py之外,还有四个如上所示的模块,每个模块完成一项简单的加减乘除操作,十分简单,调用它们时可以这样:

import f_package.mul
f_package.mul.mul(8,9)# 两数相乘为72

于是你可能发现了一些问题,在这个包里面,init.py 是一个空文件,并没有用到,而且在使用包中的模块内函数时,一层一层的用句点也未免太过麻烦;

其实__init__.py文件的作用就是导入该包内模块的成员,即把包内模块内的成员变成包内成员,这样使用起来就会更加方便;
具体操作是这样:
打开__init__.py文件编辑:

from . import add #从当前包内导入add模块
from .add import *  #从add模块中导入所有成员到包中

之后再使用add包时,就方便了一些:

import f_package as f
f.add(9,8) #两数之和为17

这只是导入了一个模块内的成员,根据需要可以选择性导入;

另外包里面也可以定义__all__变量,定义在__init__.py文件内;

部分内容(不限于本文)参考自:

菜鸟编程
廖雪峰的官方网站
c语言中文网
以及《Python编程-从入门到实践》