Python模块简介和创建及调用、包

模块(Module)简介

我们脚本上是用 python 解释器来编程,如果你从 Python 解释器退出再进入,
那么你定义的所有的方法和变量就都消失了。为此 Python 提供了一个办法,
把这些定义存放在文件中,为一些脚本或者交互式的解释器实例使用,这个文件被称为模块。

模块的定义:

模块是一个包含所有定义的函数和变量的文件,其后缀名是.py。
模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用 python 标准库的方法。

使用模块的好处:

1、提高了代码的可维护性。
2、编写代码不需要从零开始,当一个模块编写完毕,就可以被其他地方引用。
我们编写程序的时候经常引用其他模块,包括Python内置的模块和来自第三方的模块。

查看模块位置:

模块名.__file__
示例1:
In [1]: import os
In [2]: os.__file__
Out[2]: '/usr/local/lib/python3.7/os.py'
示例2:
In [3]: import psutil
In [4]: psutil.__file__
Out[4]: '/usr/local/lib/python3.7/site-packages/psutil-3.2.1-py3.7-linux-x86_64.egg/psutil/__init__.py'
#进入目录查看
In [7]: cd /usr/local/lib/python3.7/site-packages/psutil-3.2.1-py3.7-linux-x86_64.egg/psutil/
/usr/local/lib/python3.7/site-packages/psutil-3.2.1-py3.7-linux-x86_64.egg/psutil

In [8]: ls
_common.py   _pslinux.py  _psutil_linux.cpython-37m-x86_64-linux-gnu.so*  _pswindows.py
_compat.py   _psosx.py    _psutil_linux.py                                __pycache__/
__init__.py  _psposix.py  _psutil_posix.cpython-37m-x86_64-linux-gnu.so*
_psbsd.py    _pssunos.py  _psutil_posix.py

模块的意义

模块就好比是工具包,要想使用这个这个工具包中的工具(就好比函数),就需要导入这个模块

示例:
vim sendmsg.py        #创建模块
def test1():
        print("--sendmsg-test1--")
def test2():
        print("--sendmsg-test2--")

vim main.py            #创建新模块并导入之前创建的模块
import sendmsg
sendmsg.test1()
sendmsg.test2()

python3 main.py        #执行并查看模块导入后运行的结果
--sendmsg-test1--
--sendmsg-test2--
前提:两个模块必须在同一个目录下否则不能进行调用

莫夸引用后会产生一个目录文件:__pycache__
[root@localhost py]# tree __pycache__/
__pycache__/
└── sendmsg.cpython-37.pyc   #sendmsg是引用的模块名,cpython代表用c写的解析器
                             #37代表python版本3.7,.pyc是python的自解码文件

0 directories, 1 file

模块的引用

模块名.函数名 
示例:
sendmsg.test1()

引入方式的改变

有时候只需要用到模块中的某个函数,只需要引入该函数即可:
form 模块名 import 函数名1,函数名2.....

导入某个模块的函数

语法:
from modname import name1,name2,..nameN
示例1:
vim sendmsg.py        #创建模块
def test1():
        print("--sendmsg-test1--")
def test2():
        print("--sendmsg-test2--")
        
vim main.py            #创建新模块并导入之前创建的模块
from sendmsg import test1,test2
test1()
test2()

python3 main.py        #执行并查看模块导入后运行的结果
--sendmsg-test1--
--sendmsg-test2--

示例2:      #不建议使用此方式
vim sendmsg.py        #创建模块
def test1():
        print("--sendmsg-test1--")
def test2():
        print("--sendmsg-test2--")
        
vim main.py            #创建新模块并导入之前创建的模块
from sendmsg import * 
test1()
test2()

python3 main.py        #执行并查看模块导入后运行的结果
--sendmsg-test1--
--sendmsg-test2--

使用as起别名

意义:当模块名字过长时起一个短一些的别名会方便许多
示例:
In [1]: import time as tt
In [2]: tt.sleep(3)

在程序中模块是怎样加载的

In [3]: import sys          #导入外部模块
In [4]: sys.path            #想查看文件搜索路径
Out[4]: 
['/usr/local/bin',
 '/usr/local/lib/python37.zip',
 '/usr/local/lib/python3.7',
 '/usr/local/lib/python3.7/lib-dynload',
 '',
 '/usr/local/lib/python3.7/site-packages',
 '/usr/local/lib/python3.7/site-packages/psutil-3.2.1-py3.7-linux-x86_64.egg',
 '/usr/local/lib/python3.7/site-packages/IPython/extensions',
 '/root/.ipython']
# /root/.ipython只有在ipython中才加载此目录中的内容,其他地方不回加载。
#''  代表当前工作目录,从哪个目录下进入的ipython哪个目录就是所载工作目录。
#当模块放入以上任何一个位置都是可以搜索到的,都可以在ipython中直接使用

__all__变量:

如果一个文件中有__all__变量,name也就意味着这个变量中的元素,
会被from xxx import * 时导入

当有些功能不想让别人使用的时候就可以使用这种方式。


示例:
vim test.py                   #创建新的模块
num = 100
def test1():
        print("test模块中的test1函数...")
def test2():
        print("test模块中的test2函数...")
class Person(object):
        age = 18
        def __init__(self,name):
                self.name = name
        def __str__(self):
                msg = "%s的年龄是:%s"%(self.name,Person.age)
                return msg
if __name__ == '__main__':
        test1()
        test2()
        p = Person("张三")
        print(p)

vim main2.py                             #创建新模块并导入之前创建的模块
from test import *
print(num)
test1()
test2()
p = Person("李四")
print(p)
         
python3 main2.py            ##执行并查看模块导入后运行的结果
100
test模块中的test1函数...
test模块中的test2函数...
李四的年龄是:18

if __name__ == '__main__':
#测试方法,在其他模块引入时不会影响其他模块运行(此部分不会被其他模块所引用)


示例2:
vim test.py                              #创建新的模块
__all__ = ('num','test1','Person')        #只允许调用括号内的内容
num = 100
def test1():
        print("test模块中的test1函数...")
def test2():
        print("test模块中的test2函数...")
class Person(object):
        age = 18
        def __init__(self,name):
                self.name = name
        def __str__(self):
                msg = "%s的年龄是:%s"%(self.name,Person.age)
                return msg
if __name__ == '__main__':
        test1()
        test2()
        p = Person("张三")
        print(p)

vim main2.py                        #创建新模块并导入之前创建的模块
from test import *
print(num)
test1()
test2()
p = Person("李四")
print(p)

python3 main2.py                       #查看结果
100
test模块中的test1函数...
Traceback (most recent call last):
  File "main2.py", line 4, in <module>
    test2()
NameError: name 'test2' is not defined

vim main2.py                        #创建新模块并导入之前创建的模块
from test import *
import test                        #当以这种方法调用时不受__all__限制
print(num)
test1()
test.test2()
p = Person("李四")
print(p)

[root@localhost py]# python3 main2.py 
100
test模块中的test1函数...
test模块中的test2函数...
李四的年龄是:18

总结:

可以限制from test import * 导入时那些模块可以使用,不能使用未写在括号内的模块
但是import test这种调用方式不受__all__
#__all__只能限制from test import * 调用模式下的模块

模块的制作

定义自己的模块

在python中,每个python文件都可以作为一个模块,模块的名字就是文件的名字。
比如有一个文件test.py,在test.py中定义了函数add

调用自己的函数

使用__name__测试模块

示例:
vim test.py
def add(a,b):
        return a+b
def add2(a,b,opt):
        #a和b是两个数,opt是匿名函数
        result = opt(a,b)
        return result
if __name__ =='__main__':
        a = add(100,200)
        print("a+b=%s"%a)
        result = add2(100,200,lambda x,y:x*y)
        print("使用匿名函数计算:100*200=%s"%result)

[root@localhost test]# python3 test.py
a+b=300
使用匿名函数计算:100*200=20000

创建一个脚本进行调用
vim main.py
import test
a = test.add(100,200)
print("a+b=%s"%a)
result = test.add2(100,200,lambda x,y:x*y)
print("使用匿名函数计算:100*200=%s"%result)
测试:
[root@localhost test]# python3 main.py
a+b=300
使用匿名函数计算:100*200=20000

定义

包将有联系的模块组织在一起,即放在同一个文件夹下,并且在这个文件夹创建一个名字为
__init__.py的文件,那么这个文件夹就称之为包

一般情况下:__init__py文件不只是限制文件的导入,还可以做一些初始化操作

__all__在包中的作用:

在__init__.py文件中,定义一个__all__变量,它控制着from包名import *时导入的模块

可以在__init__.py文件中编写内容

示例1:
ipython
import 包名.模块名
包名.模块名.函数名()

示例2:只导入包名     #需要在__init__.py文件中写入__all__['模块名','模块名']
from 包名 import *
模块名.函数名()

包的好处

可以有效的避免模块名冲突的问题

嵌套的包

1. 目录结构

假定我们的包的例子有如下的目录结构:
Phone/
    __init__.py
    common_util.py
    Voicedta/
        __init__.py
        Pots.py
        Isdn.py
    Fax/
        __init__.py
        G3.py
    Mobile/
        __init__.py
        Analog.py
        igital.py
    Pager/
        __init__.py
        Numeric.py

2. 导入子包和使用模块

Phone 是最顶层的包,Voicedta 等是它的子包。 我们可以这样导入子包:
import Phone.Mobile.Analog 
Phone.Mobile.Analog.dial()

3. 你也可使用 from xxx import xxx 实现不同需求的导入

第一种方法是只导入顶层的子包,然后使用属性/点操作符向下引用子包树:
from Phone import Mobile
Mobile.Analog.dial('555-1212')
此外,我们可以还引用更多的子包:
from Phone.Mobile import Analog
Analog.dial('555-1212')
事实上,你可以一直沿子包的树状结构导入:
from Phone.Mobile.Analog import dial
dial('555-1212')

在我们上边的目录结构中,我们可以发现很多的 __init__.py 文件。这些是初始化模块,
from-import 语句导入子包时需要用到它。 如果没有用到,他们可以是空文件。

4. 包同样支持 from xxx import *

包同样支持 from-import all 语句:
from package.module import *

然而,这样的语句会导入哪些文件取决于操作系统的文件系统。
所以我们在__init__.py 中加入 __all__ 变量。
该变量包含执行这样的语句时应该导入的模块的名字。它由一个模块名字符串列表组成。

模块的安装

打包模块

msg目录结构
msg
    __init__py
    money
        __init__py
        msgmoney.py
    recvmsg.py
    sendmsg.py
setup.py

生成发布压缩包:

python setup.py

模块安装、使用:

1、解压 tar -zxvf xxx.tar.gz
2、进入文件夹
3、执行安装命令 sudo python setup.py install
4、指定安装位置:python setup.py install --prefix = 指定安装位置

使用安装好的模块:

在程序中,使用from import即可完成对安装的模块使用 from 模块名 import 模块名或者*

模块知识扩展

常用模块简介

Python有一套很有用的标准库(standard library)。标准库会随着Python解释器,
一起安装在你的电脑中的。 它是Python的一个组成部分。
这些标准库是Python为你准备好的利器,可以让编程事半功倍。

1. 常用标准库

标准库说明
builtins内建函数默认加载
os操作系统接口
sysPython自身的运行环境
functools常用的工具
json编码和解码 JSON 对象
logging记录日志,调试
multiprocessing多进程
threading多线程
copy拷贝
time时间
datetime日期和时间
calendar日历
hashlib加密算法
random生成随机数
re字符串正则匹配
socket标准的 BSD Sockets API
shutil文件和目录管理
glob基于文件通配符搜索
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值