python进阶(3):模块和包
之前两天我们介绍了一些比较常用的模块,而我也说过会讲解什么是模块,今天我们就来分析分析模块和包,模块我们现阶段使用还可以而包的话现阶段我们基本很少会用到包,学的不是很清楚也没关系这些东西都是用的多了也就慢慢熟悉了。
本篇导航:
一、模块
在前面的几个章节中我们脚本上是用 python 解释器来编程,如果你从 Python 解释器退出再进入,那么你定义的所有的方法和变量就都消失了。为此 Python 提供了一个办法,把这些定义存放在文件中,为一些脚本或者交互式的解释器实例使用,这个文件被称为模块。模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py。模块可以被别的程序引入,以使用该模块中的函数等功能。 这样做程序的结构更清晰,方便管理。这时我们不仅仅可以把这些文件当做脚本去执行,还可以把他们当做模块来导入到其他的模块中,实现了功能的重复利用。
1、import
print('from the my_sp.py') money=1000 def read():
print('this read:',money) def read2():
print('this read2')
read()
自定义模块my_sp
模块可以包含可执行的语句和函数的定义,这些语句的目的是初始化模块,它们只在模块名第一次遇到导入import语句时才执行(import语句是可以在程序中的任意位置使用的,且针对同一个模块很import多次,为了防止你重复导入,python的优化手段是:第一次导入后就将模块名加载到内存了,后续的import语句仅是对已经加载大内存中的模块对象增加了一次引用,不会重新执行模块内的语句), 我们可以从sys.module中找到当前已经加载的模块,sys.module是一个字典,内部包含模块名与模块对象的映射,该字典决定了导入模块时是否需要重新导入。
import my_sp #导入刚自己定义的模块
my_sp.read() #使用函数 import sys #调用sys模块
#作用:显示现在程序调用的所用模块
for i in sys.modules :
print(i)
import
2、命名空间
每个模块都是一个独立的名称空间,定义在这个模块中的函数,把这个模块的名称空间当做全局名称空间,这样我们在编写自己的模块时,就不用担心我们定义在自己模块中全局变量会在被导入时,与使用者的全局变量冲突
1)为源文件(my_sp模块)创建新的名称空间,在my_sp中定义的函数和方法若是使用到了global时访问的就是这个名称空间。
2)在新创建的命名空间中执行模块中包含的代码
3)创建名字my_sp来引用该命名空间
3、模块别名
import my_sp as sp
sp.read()
别名
使用实例:
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()
#目的是链接哪个数据库都可以不用修改代码
示例用法1(了解即可)
2)为已经导入的模块起别名的方式对编写可扩展的代码很有用,假设有两个模块xmlreader.py和csvreader.py,它们都定义了函数read_data(filename):用来从文件中读取一些数据,但采用不同的输入格式。可以编写代码来选择性地挑选读取模块
if file_format == 'xml':
import xmlreader as reader
elif file_format == 'csv':
import csvreader as reader
data=reader.read_date(filename)
示例用法2
4、from...import
这种形式是导入啥就能用啥,不导入的一律不能用,这个被import的名字就属于全局,可以节省空间。from 语句相当于import,也会创建新的名称空间,但是将my_sp中的名字直接导入到当前的名称空间中,在当前名称空间中,直接使用名字就可以了
from my_sp import read1 #可以直接使用read1
read1() #my_sp里面的其他方法和变量将不能再用
from...import
如果当前有重名read1那么会有覆盖效果。
也支持as
from my_sp import read1 as rd
5、from 模块 import *
首先会把模块当中所有不是‘_’开头的内容导入进来
还可以通过__all__来控制可以导入的内容(如果不使用__all__就可以导入所有名字)
但是 以上两条只和 * 有关
不建议使用
6、importlib
import time,importlib
import my_sp my_sp.read() time.sleep(10) # importlib.reload(my_sp)
my_sp.read() #在10秒的等待时间里,修改my_sp.py中read()的内容,等待程序的结果。 #打开importlib注释,重新测试 #importlib可以重新加载模块但是不建议使用
importlib
7、__name__
我们可以通过模块的全局变量__name__来查看模块名:
当做脚本运行:
__name__ 等于'__main__'
当做模块导入:
__name__= 模块名
作用:用来控制.py文件在不同的应用场景下执行不同的逻辑
if __name__ == '__main__':
8、模块搜索路径
python解释器在启动时会自动加载一些模块,可以使用sys.modules查看
解释器则会查找同名的内建模块,如果还没有找到就从sys.path给出的目录列表中依次寻找my_module.py文件。
模块的查找顺序是:内存中已经加载的模块->内置模块->sys.path路径中包含的模块
import sys
print(sys.path)
#['G:\\python\\python代码\\八月\\day9 模块与包', 'G:\\python\\python代码', 'G:\\python\\Python36\\python36.zip', 'G:\\python\\Python36\\DLLs', 'G:\\python\\Python36\\lib', 'G:\\python\\Python36', 'G:\\python\\Python36\\lib\\site-packages']
我们自定义的模块名不应该与系统内置模块重名。因为排在前的目录,优先被搜索这样我们就无法导入内置模块。python会把.zip归档文件当成一个目录去处理。
9、编译python文件
为了提高加载模块的速度,强调:提高的是加载速度而绝非运行速度。python解释器会在__pycache__目录中下缓存每个模块编译后的版本,格式为:__pycache__/my_sp.cpython-36.pyc。这种命名规范保证了编译后的结果多版本共存。(36为版本)
它的出现仅仅是用来提升模块的加载速度的。
python -m my_sp.py
提示:
1)模块名区分大小写
2)在速度上从.pyc文件中读指令来执行不会比从.py文件中读指令执行更快,只有在模块被加载时,.pyc文件才是更快的
3)个人认为没有必要去单独编译,因为当你import导入模块时会自动编译
10、dir()
内建函数dir是用来查找模块中定义的名字,返回一个有序字符串列表
import my_sp
print(dir(my_sp))
二、包
包个人概括:
1)无论是import形式还是from...import形式,凡是在导入语句中使用点的(一般是表示相对路径)
2)包的本质就是一个包含__init__.py文件的目录
3)导入包本质就是在导入该文件
4)包只是模块的一种形式而已,包即模块(包为文件夹,模块为文件)
import os
os.makedirs('glance/api')
os.makedirs('glance/cmd')
os.makedirs('glance/db')
l = []
l.append(open('glance/__init__.py','w'))
l.append(open('glance/api/__init__.py','w'))
l.append(open('glance/api/policy.py','w'))
l.append(open('glance/api/versions.py','w'))
l.append(open('glance/cmd/__init__.py','w'))
l.append(open('glance/cmd/manage.py','w'))
l.append(open('glance/db/__init__.py','w'))
l.append(open('glance/db/models.py','w'))
map(lambda f:f.close() ,l)
创建包目录
#文件内容(在相应的文件里输入以便测试) #policy.py
def get():
print('from policy.py') #versions.py
def create_resource(conf):
print('from version.py: ',conf) #manage.py
def main():
print('from manage.py') #models.py
def register_models(engine):
print('from models.py: ',engine)
文件内容
1、import
import glance.db.models
glance.db.models.register_models('hello')
2、from...import
from后import导入的模块,必须是明确的一个不能带点
#from glance.db import models.register_models #报错 from glance.db.models import register_models
register_models("hello")
3、__int__文件
不管是哪种方式,只要是第一次导入包或者是包的任何其他部分,都会依次执行包下的__init__.py文件。这个文件可以为空,但是也可以存放一些初始化包的代码。
4、from glance.api import *
在讲模块时,我们已经讨论过了从一个模块内导入所有*,包也是模块那么我们也研究从一个包导入所有*。
此处是想从包api中导入所有,实际上该语句只会导入包api下__init__.py文件中定义的名字,我们可以在这个文件中定义__all___:
#在api文件夹下的__init__.py文件中定义
__all__=['policy','versions']
5、绝对导入和相对导入
绝对导入:以glance作为起始
相对导入:用.或者..的方式最为起始(.为本层目录,..为上层目录)
#在api目录下的文件内:
from . import policy #.表示当前目录
from ..cmd import manage #..表示上一级目录,想再api目录下的文件内中使用manage中的方法就需要回到上一级glance目录往下找cmd包,从cmd导入manage
注意:
相对导包,包程序不能单独运行会报错。只能由包外部导入使用。简单说就是导包时有from后面直接跟.的不能直接运行
6、单独导入包
import glance
glance.cmd.manage.main()
#报错
解决方法:
#glance/__init__.py
from . import cmd #glance/cmd/__init__.py
from . import manage #api,db同理
单独导入包解决1
#glance/__init__.py
from .api import *
from .cmd import *
from .db import * #glance/cmd/__init__.py
__all__ = ['manage'] #api,db同理
单独导入包解决2
小知识:
软件开发规范:
#=============>bin目录:存放执行脚本
#start.py #=============>conf目录:存放配置文件
#config.ini
#my_log_settings.py
#settings.py #=============>core目录:存放核心逻辑
#core.py #=============>db目录:存放数据库文件
#alex_json
#egon_json #=============>lib目录:存放自定义的模块与包
#read_ini.py #=============>log目录:存放日志
#all2.log
python进阶(3):模块和包的更多相关文章
- Python进阶之模块与包
模块 .note-content {font-family: "Helvetica Neue",Arial,"Hiragino Sans GB","S ...
- Python进阶----pymysql模块的使用,单表查询
Python进阶----pymysql模块的使用,单表查询 一丶使用pymysql 1.下载pymysql包: pip3 install pymysql 2.编写代码 ...
- 二十五. Python基础(25)--模块和包
二十五. Python基础(25)--模块和包 ● 知识框架 ● 模块的属性__name__ # my_module.py def fun1(): print("Hello& ...
- Python进阶(八)----模块,import , from import 和 `__name__`的使用
Python进阶(八)----模块,import , from import 和 __name__的使用 一丶模块的初识 #### 什么是模块: # 模块就是一个py文件(这个模块存放很多相似的功能, ...
- Python 进阶_模块 & 包
目录 目录 模块的搜索路径和路径搜索 搜索路径 命名空间和变量作用域的比较 变量名的查找覆盖 导入模块 import 语句 from-import 语句 扩展的 import 语句 as 自动载入模块 ...
- Python进阶之模块
在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很 ...
- python中的模块及包及软件目录结构规范
知识内容: 1.模块的定义与分类 2.模块的导入 3.模块与包 4.不同目录下的模块调用 一.模块的定义与分类 1.什么是模块 模块就是实现了某个功能的代码集合,模块是由一大堆代码构成的 类似于函数式 ...
- Python中的模块与包
标准库的安装路径 在import模块的时候,python是通过系统路径找到这些模块的,我们可以将这些路径打印出来: >>> pprint.pprint(sys.path) ['', ...
- 【循序渐进学Python】10.模块和包
1.导入模块 任何Python程序都可以作为模块导入,只要Python解释器能找到我们定义的模块所在位置即可,一般来讲,在一个模块被导入时,Python解释器会按照下面的步骤进行搜索: 在当前所在目录 ...
- Python类、模块、包的区别
类 类的概念在许多语言中出现,很容易理解.它将数据和操作进行封装,以便将来的复用. 模块 模块,在Python可理解为对应于一个文件.在创建了一个脚本文件后,定义了某些函数和变量.你在其他需要这些功能 ...
随机推荐
- nginx+ftp搭建图片服务器(Windows Server服务器环境下)
几种图片服务器的对比 1.直接使用ftp服务器,访问图片路径为 ftp://账户:密码@192.168.0.106/31275-105.jpg 不采用这种方式,不安全容易暴露ftp账户信息 2.直接使 ...
- ES6中的export以及import的使用多样性
模块功能主要由两个命令构成:export和import.export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能. 一.export导出模块使用部分的几种方式 一个模块就是一 ...
- [leetcode-598-Range Addition II]
Given an m * n matrix M initialized with all 0's and several update operations. Operations are repre ...
- Chapter 5. MPEG-4 Visual
本章着重介绍有关MPEG-4 Visual标准的细节. Tool 编码工具集合的子集(比如支持交织等). Object 视频元素(比如一个矩形视频帧,或者一个任意形状的区域,静止的图像). Profi ...
- 从栈不平衡问题 理解 calling convention
最近在开发的过程中遇到了几个很诡异的问题,造成了栈不平衡从而导致程序崩溃. 经过几经排查发现是和调用规约(calling convention)相关的问题,特此分享出来. 首先,讲一下什么是调用规约. ...
- winform .net2.0的程序如何运行于.net 4.x
约束 最近有一个winform项目,要求: (1)程序能够运行在winxp, win7, win8, win10中 (2)安装尽可能简单,尽量不要安装.net framework.即使要安装也要尽可以 ...
- python简单实现websocket
协议选择的是新的Hybi-10,参考文章如下: http://www.cnblogs.com/zhuweisky/p/3930780.html http://blog.mycolorway.com/2 ...
- VB6之CRC32
翻译篇:http://www.cnblogs.com/duzouzhe/archive/2009/08/05/1539543.html Private Declare Function GetTick ...
- jmeter-Java关于MD5加密方法 以及16位32位互转
MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致.是计算机广泛使用的杂凑算法之一(又译摘要算法.哈希算法),主流编程语言普遍已有MD5实现.将 ...
- STL—list
前面我们分析了vector,这篇介绍STL中另一个重要的容器list list的设计 list由三部分构成:list节点.list迭代器.list本身 list节点 list是一个双向链表,所以其li ...