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可理解为对应于一个文件.在创建了一个脚本文件后,定义了某些函数和变量.你在其他需要这些功能 ...
随机推荐
- python爬虫从入门到放弃前奏之学习方法
首谈方法 最近在整理爬虫系列的博客,但是当整理几篇之后,发现一个问题,不管学习任何内容,其实方法是最重要的,按照我之前写的博客内容,其实学起来还是很点枯燥不能解决传统学习过程中的几个问题: 这个是普通 ...
- 搭建开源java博客并通过域名访问
这个博客系统是王爵在GitHub上开源的,通过简单几步就可以部署成功. 前面几步可以参照如下几个链接: 1.https://www.qcloud.com/community/article/29008 ...
- JS面向对象一
面向对象分为三大类 封装,继承,多态! 封装就是在一个函数方法中嵌套另外一个函数方法,外层函数方法返回内层函数方法里面的结果,其中内层函数要调用外层函数定义的局部变量 每个函数方法就是一个局部作用域, ...
- 网页标题title的闪动提示
<!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...
- 【Socket】Java Socket基础编程
Socket是Java网络编程的基础,了解还是有好处的, 这篇文章主要讲解Socket的基础编程.Socket用在哪呢,主要用在进程间,网络间通信.本篇比较长,特别做了个目录: 一.Socket通信基 ...
- View学习(二)-View的测量(measure)过程
在上一篇文章中,我们介绍了DecorView与MeasureSpec, 下面的文章就开始讨论View的三大流程. View的三大流程都是通过ViewRoot来完成的.ViewRoot对应于ViewRo ...
- Vue--props
组件实例的作用域是孤立的.这意味着不能 (也不应该) 在子组件的模板内直接引用父组件的数据.要让子组件使用父组件的数据,我们需要通过子组件的 props 选项. 字面量语法 vs 动态语法 初学者常犯 ...
- php 时间问题
获得简单的日期 date() 函数的格式参数是必需的,它们规定如何格式化日期或时间. 下面列出了一些常用于日期的字符: d - 表示月里的某天(01-31) m - 表示月(01-12) Y - 表示 ...
- Django学习(四)---Admin配置
1)Admin: admin是django自带的功能强大的自动化数据管理界面 被授权的用户可以直接在Admin中管理数据库(增.删.改.查) Django提供了许多针对Admin的定制功能 2)配置A ...
- CSS3-loading动画(五)
CSS3-loading加载动画 在线示例demo:http://liyunpei.xyz/loading.html 之前发了四篇,二十二个效果,今天再分享六个效果,总计二十八个效果. 二十三.效果二 ...