设为首页 收藏本站
查看: 829|回复: 0

[经验分享] python基础---模块与包

[复制链接]

尚未签到

发表于 2018-8-9 08:53:23 | 显示全部楼层 |阅读模式
  1、模块导入方法
  常见的场景:
  一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀,导入模块可以实现功能的重复利用
  import加载的模块分为四个通用类别: 
  1 使用python编写的代码(.py文件)
  2 已被编译为共享库或DLL的C或C++扩展
  3 包好一组模块的包
  4 使用C编写并链接到python解释器的内置模块
  a. import语句
  python 内置了很多模块,比如os、sys、time等,也可以是自定义模块、模块包、C扩展等,使用import无法区分导入的模块类型
  import 模块名
  例如:导入spam.py
  import spam(不含.py)
  导入多个模块:
  import os,time,sys
  模块可以包含可执行的语句和函数的定义,这些语句的目的是初始化模块,它们只在模块名第一次遇到导入import语句时才执行(import语句是可以在程序中的任意位置使用的,且针对同一个模块import很多次,为了防止你重复导入,python的优化手段是:第一次导入后就将模块名加载到内存了,后续的import语句仅是对已经加载大内存中的模块对象增加了一次引用,不会重新执行模块内的语句)
  每个模块都是一个独立的名称空间,定义在这个模块中的函数,把这个模块的名称空间当做全局名称空间,这样我们在编写自己的模块时,就不用担心我们定义在自己模块中全局变量会在被导入时,与使用者的全局变量冲突
  导入模块干了哪些事:
  1 执行源文件
  2 以一个源文件的全局名称空间
  3 在当前位置拿到一个模块名,指向2创建的名称空间
#测试一:money与spam.money不冲突  
#test.py
  
import spam
  
money=10
  
print(spam.money)
  

  
输出:
  
from the spam.py
  
1000
  

  
#测试二:read1与spam.read1不冲突
  
#test.py
  
import spam
  
def read1():
  
     print('========')
  
spam.read1()
  

  
输出:
  
from the spam.py
  
spam->read1->money1000
  

  
#测试三:执行spam.change()操作的全局变量money仍然是spam中的
  
#test.py
  
import spam
  
money=1
  
spam.change()
  
print(money)
  

  
输出:
  
from the spam.py
  
1
  模块别名功能
  练习:
  有两钟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()
  为已经导入的模块起别名的方式对编写可扩展的代码很有用,假设有两个模块xmlreader.py和csvreader.py,它们都定义了函数read_data(filename):用来从文件中读取一些数据,但采用不同的输入格式。可以编写代码来选择性地挑选读取模块
if file_format == 'xml':  
    import xmlreader asreader
  
elif file_format == 'csv':
  
    import csvreader asreader
  
data=reader.read_date(filename)
  b. from…import语句
  from 模块名  import 模块名中的方法
  例如:from spamimport money,read1,read2,change
  如果模块中的方法太多,可以使用:
  from spam import  *     (不推荐使用,容易与执行文件的命名空间冲突)
  __all__=['money','x']      #对from spam import * 有用,之后导入money、x方法
  _money=1000             #对from spam import * 有用,不会导入这个方法
  对比import spam,会将源文件的名称空间'spam'带到当前名称空间中,使用时必须是spam.名字的方式,而from 语句相当于import,也会创建新的名称空间,但是将spam中的名字直接导入到当前的名称空间中,在当前名称空间中,直接使用名字就可以了
#spam.py  
print('from the spam.py')
  

  
money=0
  
def read1():
  
    print('spam->read1->money',money)
  

  
def read2():
  
    print('spam->read2 calling read')
  
    read1()
  

  
def change():
  
    global money
  
    money=0
  

  
# 执行文件
  
from spam import money,read1,read2,change
  
money=0
  
print(money)
  
print(read1)
  

  
输出:
  
from the spam.py                    #首先执行spam.py
  
0                      #仍然是当前执行文件的命名空间中的money
  
<function read1 at 0x00000000026DE950>
  优点:使用源文件内的名字时无需加前缀,使用方便
  缺点:容易与当前文件的名称空间内的名字混淆
  c. 模块搜索路径
  模块只在第一次导入时才会执行,之后的导入都是直接引用内存已经存在的结果
  import sys
  print('spam' in sys.modules)            #存放的是已经加载到内的模块
  注意:自定义的模块名一定不要与python自带的模块名重名
  模块的查找顺序是:内存中已经加载的模块->内置模块->sys.path路径中包含的模块
import time  
import importlib
  

  
import spam           #导入模块会把硬盘中的模块内容加载到内存中
  
time.sleep(20)
  
import spam           #再次导入会直接从内存中查找,忽略硬盘中模块内容
  
print(spam.money)
  
importlib.reload(spam)         #会重新加载模块(只在测试环境使用)
  
print(spam.money)
  import sys
  print(sys.path)              #模块的搜索路径
  sys.path从以下位置初始化
  1  执行文件所在的当前目录
  2  PTYHONPATH(包含一系列目录名,与shell变量PATH语法一样)
  3  依赖安装时默认指定的
  加入模块路径:
import sys  
print(sys.path)
  
sys.path.insert(0,r'要添加的模块路径')       #插入模块路径
  
sys.path.append(r'要添加的模块路径')         #追加模块路径
  d. 区分python文件的两种用途
  文件当做脚本(执行文件)运行时__name__等于__main__
  文件当做模块被加载运行时__name__等于模块名
# m1.py  
import os,sys
  
x=1
  
def func1():
  
    print('from m1')
  
def func2():
  
    print('from m2')
  
def func3():
  
    print('from m3')
  
# print(__name__)
  
#文件当做脚本运行时__name__等于__main__
  
#文件当做模块被加载运行时__name__等于模块名
  
if __name__ == '__main__':
  
    #当做脚本使用时才执行
  
    func1()
  
    func2()
  
    func3()
  
# run.py
  

  
import m1            #导入m1模块
  
m1.func3()
  e. 包
  python3中创建文件夹会自动创建__init__.py
  python2中创建包需要手动创建__init__.py
  1. 无论是import形式还是from...import形式,凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高警觉:这是关于包才有的导入语法
  2. 包是目录级的(文件夹级),文件夹是用来组成py文件(包的本质就是一个包含__init__.py文件的目录)
  3. import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件
  强调:
  1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错
  2. 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包即模块
  3.凡是在导入时带点的,点的左边都必须是一个包

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-548927-1-1.html 上篇帖子: python_day8_异常处理 下篇帖子: Python 自动化运维 dnspython-777777
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表