python之路---模块与包
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python之路---模块与包相关的知识,希望对你有一定的参考价值。
模块与包 (官网https://docs.python.org/3/contents.html)
1.模块
1.1 一个.py文件 (内容一般是定义的函数或者数据或者方法) 就可以当做一个模块 可以被调用
1.2 模块可以包含可执行的语句和函数的定义,这些语句的目的是初始化模块,它们只在模块名第一次遇到导入import语句时才执行(import语句是可以在程序中的任意位置使用的,且针对同一个模块很import多次,为了防止你重复导入,python的优化手段是:第一次导入后就将模块名加载到内存了,后续的import语句仅是对已经加载大内存中的模块对象增加了一次引用,不会重新执行模块内的语句)
1 #test.py 2 import spam #只在第一次导入时才执行spam.py内代码,此处的显式效果是只打印一次‘from the spam.py‘,当然其他的顶级代码也都被执行了,只不过没有显示效果. 3 import spam 4 import spam 5 import spam 6 7 ‘‘‘ 8 执行结果: 9 from the spam.py 10 ‘‘‘
1.3 每个模块都是有自己独立的名称空间,定义在模块的名称空间 可以当做全局名称空间,
自己模块的全局变量 不会与导入模块的去哪聚名称空间相冲突
示例文件:spam.py,文件名spam.py,模块名spam #spam.py print(‘from the spam.py‘) money=1000 def read1(): print(‘spam->read1->money‘,money) def read2(): print(‘spam->read2 calling read‘) read1() def change(): global money money=0 ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... ......................................... 11111111111111111111 #test.py import spam #只在第一次导入时才执行spam.py内代码,此处的显式效果是只打印一次‘from the spam.py‘,当然其他的顶级代码也都被执行了,只不过没有显示效果. import spam import spam import spam ‘‘‘ 执行结果: from the spam.py ‘‘‘ 2222222222222222222222 #测试二:read1与spam.read1不冲突 #test.py import spam def read1(): print(‘========‘) spam.read1() ‘‘‘ 执行结果: from the spam.py spam->read1->money 1000 ‘‘‘ 333333333333333333333333333 #测试三:执行spam.change()操作的全局变量money仍然是spam中的 #test.py import spam money=1 spam.change() print(money) ‘‘‘ 执行结果: from the spam.py 1 ‘‘‘
2.导入模块
首次导入模块时会做的三件事:
1.为源文件创建新的名称空间,在模块中定义的函数和方法若是使用到了global时访问的就是这个模块的名称空间
2.导入模块时执行了该导入模块中包含的代码,语法是import+导入模块的名字
2.1 为模块起别名 相当m1=1,m2=m1
1 import spam as sm
2 print(sm.money)
示范用法一:
有两中sql模块mysql和oracle,根据用户的输入,选择不同的sql功能
#mysql.py def sqlparse(): print(‘from mysql sqlparse‘) #oracle.py def sqlparse(): print(‘from oracle sqlparse‘) #test.py db_type=input(‘>>: ‘) if db_type == ‘mysql‘: import mysql as db elif db_type == ‘oracle‘: import oracle as db db.sqlparse()
2.1 from ... import ...
相当于import , 同样会执行一遍my_module文件 , 同样也会创建命名空间 , 但是from .. . import ... 是将my_module中的名字直接导入到当前的命名空间 , 也就意味着可以直接调用 , 而不用像import那样 , 利用 my_module . 名字 来进行调用
两种方式对比
# import方式 import my_module # 模块名 + ‘.‘ + 函数名进行调用 my_module.read() # from...import...方式 from my_module import read # 直接用函数名调用 read()
PS : 利用from...import...方式进行导入 , 一般用来指定导入模块中的某一部分 , 或者方便使用 , 还有一个特殊的导入 from ... import * (作用是导入模块中的所有内容 , 但是有弊端)
as
from my_module import read as r
多行
from my_module import (read1,
read2,
read3)
2.1.1from ... import * 把模块中所有的不是以下划线(_)开头的名字都导入到当前位置,大部分情况下我们的python程序不应该使用这种导入方式,因为*你不知道你导入什么名字,很有可能会覆盖掉你之前已经定义的名字。而且可读性极其的差,在交互式环境中导入时没有问题。
from my_module import * #将模块my_module中所有的名字都导入到当前名称空间 print(money) print(read1) print(read2) print(change) ‘‘‘ 执行结果: from the my_module.py <function read1 at 0x1012e8158> <function read2 at 0x1012e81e0> <function change at 0x1012e8268> ‘‘‘
在模块.py中新增一行
__all__=[‘money‘,‘read1‘] #这样在另外一个文件中用from my_module import *就这能导入列表中规定的两个名字
*如果my_module.py中的名字前加_,即_money,则from my_module import *,则_money不能被导入
2.2 模块当做脚本运行
if __name__ == ‘__main__‘
所有的模块都有一个内置属性 __name__ , 可以用来查看模块名
在当前文件执行时会返回‘ _main_ ‘, 如果不在当前文件执行那么就会返回所执行的模块名
# my_module.py中 print(__name__) # 执行my_module.py 执行结果: __main__ # test.py中 import my_modlue # 执行 test.py 执行结果: my_module
2.3模块搜索路径
python解释器在启动时会自动加载一些模块,可以使用sys.modules查看
在第一次导入某个模块时(比如my_module),会先检查该模块是否已经被加载到内存中(当前执行文件的名称空间对应的内存),如果有则直接引用
如果没有,解释器则会查找同名的内建模块,如果还没有找到就从sys.path给出的目录列表中依次寻找my_module.py文件。
所以总结模块的查找顺序是:内存中已经加载的模块->内置模块->sys.path路径中包含的模块
需要特别注意的是:我们自定义的模块名不应该与系统内置模块重名
需要特别注意的是:我们自定义的模块名不应该与系统内置模块重名
需要特别注意的是:我们自定义的模块名不应该与系统内置模块重名
包
以上是关于python之路---模块与包的主要内容,如果未能解决你的问题,请参考以下文章