博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
day21.模块和包
阅读量:5277 次
发布时间:2019-06-14

本文共 3947 字,大约阅读时间需要 13 分钟。

博客整理来源:http://www.cnblogs.com/Eva-J/articles/7292109.html

模块

1.什么是模块

常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀。

 但其实import加载的模块分为四个通用类别: 

  1 使用python编写的代码(.py文件)

  2 已被编译为共享库或DLL的C或C++扩展

  3 包好一组模块的包

  4 使用C编写并链接到python解释器的内置模块

2.为何要使用模块

  如果你退出python解释器然后重新进入,那么你之前定义的函数或者变量都将丢失,因此我们通常将程序写到文件中以便永久保存下来,

需要时就通过python test.py方式去执行,此时test.py被称为脚本script。

    随着程序的发展,功能越来越多,为了方便管理,我们通常将程序分成一个个的文件,这样做程序的结构更清晰,方便管理。

这时我们不仅仅可以把这些文件当做脚本去执行,还可以把他们当做模块来导入到其他的模块中,实现了功能的重复利用,

3.如何使用模块

3.1 import

示例文件:自定义模块my_module.py,文件名my_module.py,模块名my_module

#my_module.pyprint('from the my_module.py')money=1000def read1():    print('my_module->read1->money',money)def read2():    print('my_module->read2 calling read1')    read1()def change():    global money    money=0

 3.1.1  模块单次调用                              

模块可以包含可执行的语句和函数的定义,这些语句的目的是初始化模块,它们只在模块名第一次遇到导入import语句时才执行.

模块第一次导入后加载进内存,后续的import语句加载内存模块,不会重复调用

#demo.pyimport my_module #只在第一次导入时才执行my_module.py内代码,此处的显式效果是只打印一次'from the my_module.py',当然其他的顶级代码也都被执行了,只不过没有显示效果.import my_moduleimport my_moduleimport my_module'''执行结果:from the my_module.py'''

3.1.2 模块变量不会影响自定义变量                      

每个模块都是一个独立的名称空间,定义在这个模块中的函数,把这个模块的名称空间当做全局名称空间,这样我们在编写自己的模块时,

就不用担心我们定义在自己模块中全局变量会在被导入时,与使用者的全局变量冲突

 

#测试一:money与my_module.money不冲突#demo.pyimport my_modulemoney=10print(my_module.money) print(money)'''执行结果:from the my_module.py 1000 10'''
#测试二:read1与my_module.read1不冲突#demo.pyimport my_moduledef read1():    print('========')my_module.read1()'''执行结果:from the my_module.pymy_module->read1->money 1000'''

3.1.3 总结                 

总结:首次导入模块my_module时会做3件事

1.为源文件(my_module模块)创建新的名称空间,在my_module中定义的函数和方法若是使用到了global时访问的就是这个名称空间。

2.在新创建的命名空间中执行模块中包含的代码,见初始导入import my_module

3.创建名字my_module来引用该命名空间

3.1.4 为模块重命名            

事例1:方便调用

有两中sql模块mysql和oracle,根据用户的输入,选择不同的sql功能

#mysql.pydef sqlparse():    print('from mysql sqlparse')#oracle.pydef sqlparse():    print('from oracle sqlparse')#test.pydb_type=input('>>: ')if db_type == 'mysql':    import mysql as db    # 将mysql 和oracle 都命名为 db,调用mysql或oracle都可直接调用db,方便快捷elif db_type == 'oracle':    import oracle as db

3.1.5 一行导入多个模块 (不常用)   

import sys,os,re

3.2 from ... import ...

3.2.1                      

对比import my_module,会将源文件的名称空间'my_module'带到当前名称空间中,使用时必须是my_module.名字的方式

而from 语句相当于import,也会创建新的名称空间,但是将my_module中的名字直接导入到当前的名称空间中,在当前名称空间中,直接使用名字就可以了、

#测试一:导入的函数read1,执行时仍然回到my_module.py中寻找全局变量money#demo.pyfrom my_module import read1money=100read1()'''执行结果:from the my_module.pyspam->read1->money 1000'''#测试二:导入的函数read2,执行时需要调用read1(),仍然回到my_module.py中找read1()#demo.pyfrom my_module import read2def read1():    print('==========')read2()'''执行结果:from the my_module.pymy_module->read2 calling read1my_module->read1->money 1000'''

如果当前有重命名read1或者read2,那么会有覆盖现象。(函数级别)

#测试三:导入的函数read1,被当前位置定义的read1覆盖掉了#demo.pyfrom my_module import read1def read1():    print('==========')read1()'''执行结果:from the my_module.py=========='''

需要特别强调的一点是:python中的变量赋值不是一种存储操作,而只是一种绑定关系,如下:

 

from my_module import money,read1money=100 #将当前位置的名字money绑定到了100print(money) #打印当前的名字read1() #读取my_module.py中的名字money,仍然为1000'''from the my_module.pymy_module->read1->money 1000'''

3.2.2  也支持重命名        

3.2.3  也支持多行导入        

3.3 把模块当做脚本执行

我们可以通过模块的全局变量__name__来查看模块名:

当做脚本运行:
__name__ 等于'__main__'

当做模块导入:

__name__= 模块名

作用:用来控制.py文件在不同的应用场景下执行不同的逻辑

if __name__ == '__main__':

# 模块aa = 100print('这是模块a')if __name__ == '__main__':    print(a)# 模块bimport ab = 200print('这是模块b')print(b) # 在模块 b 中调入模块a 的执行结果:这是模块a这是模块b200

当你要导入某个模块,但又不想改模块的部分代码被直接执行,那就可以这一部分代码放在“if __name__=='__main__':

二 包

1. 无论是import形式还是from...import形式,凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高警觉:这是关于包才有的导入语法

2. 包是目录级的(文件夹级),文件夹是用来组成py文件(包的本质就是一个包含__init__.py文件的目录)

3. import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件

强调:

  1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错

  2. 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包即模块

 

转载于:https://www.cnblogs.com/jiuyachun/p/10592604.html

你可能感兴趣的文章
线程5--GCD简介
查看>>
一个弹出层代码
查看>>
全选,反全选,反选,获取选中的值,根据子选择控制全选按钮
查看>>
梦断代码读后感01
查看>>
[CF#250 Div.2 D]The Child and Zoo(并查集)
查看>>
博客园博客插入公式
查看>>
spring ioc原理(看完后大家可以自己写一个spring)
查看>>
hdu 1028 Ignatius and the Princess III(母函数入门+模板)
查看>>
Ubuntu下配置安装telnet server
查看>>
Codeforces 235 E Number Challenge
查看>>
ubuntu 常见命令整理
查看>>
关于vue的npm run dev和npm run build
查看>>
微信小程序手机调试
查看>>
Hive架构
查看>>
Windows 2019 docker 速记
查看>>
设计模式学习笔记(二十二:备忘录模式)
查看>>
第二轮冲刺-Runner站立会议09
查看>>
HTML <base> 标签
查看>>
getDefinitionByName与ApplicationDomain.getDefinition
查看>>
那墙可有五十米高啊!
查看>>