python之旅:模块与包
一、模块介绍
前言:引用廖雪峰大神的,说的很好!!!
在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护。
为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。在Python中,一个.py文件就称之为一个模块(Module)。
使用模块有什么好处?
最大的好处是大大提高了代码的可维护性。其次,编写代码不必从零开始。当一个模块编写完毕,就可以被其他地方引用。我们在编写程序的时候,也经常引用其他模块,包括Python内置的模块和来自第三方的模块。
使用模块还可以避免函数名和变量名冲突。相同名字的函数和变量完全可以分别存在不同的模块中,因此,我们自己在编写模块时,不必考虑名字会与其他模块冲突。但是也要注意,尽量不要与内置函数名字冲突。点这里查看Python的所有内置函数。
你也许还想到,如果不同的人编写的模块名相同怎么办?为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package)。
举个例子,一个
abc.py的文件就是一个名字叫abc的模块,一个xyz.py的文件就是一个名字叫xyz的模块。现在,假设我们的
abc和xyz这两个模块名字与其他模块冲突了,于是我们可以通过包来组织模块,避免冲突。方法是选择一个顶层包名,比如mycompany,按照如下目录存放:mycompany
├─ __init__.py
├─ abc.py
└─ xyz.py
引入了包以后,只要顶层的包名不与别人冲突,那所有模块都不会与别人冲突。现在,
abc.py模块的名字就变成了mycompany.abc,类似的,xyz.py的模块名变成了mycompany.xyz。请注意,每一个包目录下面都会有一个
__init__.py的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。__init__.py可以是空文件,也可以有Python代码,因为__init__.py本身就是一个模块,而它的模块名就是mycompany。类似的,可以有多级目录,组成多级层次的包结构。比如如下的目录结构:
mycompany
├─ web
│ ├─ __init__.py
│ ├─ utils.py
│ └─ www.py
├─ __init__.py
├─ abc.py
└─ xyz.py
文件
www.py的模块名就是mycompany.web.www,两个文件utils.py的模块名分别是mycompany.utils和mycompany.web.utils。!!! 自己创建模块时要注意命名,不能和Python自带的模块名称冲突。例如,系统自带了sys模块,自己的模块就不可命名为sys.py,否则将无法导入系统自带的sys模块。
mycompany.web也是一个模块,请指出该模块对应的.py文件。总结
模块是一组Python代码的集合,可以使用其他模块,也可以被其他模块使用。
创建自己的模块时,要注意:
模块名要遵循Python变量命名规范,不要使用中文、特殊字符;
模块名不要和系统模块名冲突,最好先查看系统是否已存在该模块,检查方法是在Python交互环境执行
import abc,若成功则说明系统存在此模块。
1、什么是模块?
#常见的场景:一个模块就是一个包含了一组功能的python文件,比如spam.py,模块名为spam,可以通过import spam使用。 #在python中,模块的使用方式都是一样的,但其实细说的话,模块可以分为四个通用类别:
使用python编写的.py文件
已被编译为共享库或DLL的C或C++扩展
把一系列模块组织到一起的文件夹(注:文件夹下有一个__init__.py文件,该文件夹称之为包)
使用C编写并链接到python解释器的内置模块
2、为何要使用模块?
#1、从文件级别组织程序,更方便管理
随着程序的发展,功能越来越多,为了方便管理,我们通常将程序分成一个个的文件,这样做程序的结构更清晰,方便管理。这时我们不仅仅可以把这些文件当做脚本去执行,还可以把他们当做模块来导入到其他的模块中,实现了功能的重复利用 #2、拿来主义,提升开发效率
同样的原理,我们也可以下载别人写好的模块然后导入到自己的项目中使用,这种拿来主义,可以极大地提升我们的开发效率 #ps:
如果你退出python解释器然后重新进入,那么你之前定义的函数或者变量都将丢失,因此我们通常将程序写到文件中以便永久保存下来,需要时就通过python test.py方式去执行,此时test.py被称为脚本script。
3、下面以spam.py为例来介绍模块的使用:文件名spam.py,模块名spam
#spam.py
print('from the spam.py') money=1000 def read1():
print('spam模块:',money) def read2():
print('spam模块')
read1() def change():
global money
money=0
二、使用模块之import
1、import的使用
#模块可以包含可执行的语句和函数的定义,这些语句的目的是初始化模块,它们只在模块名第一次遇到导入import语句时才执行(import语句是可以在程序中的任意位置使用的,且针对同一个模块很import多次,为了防止你重复导入,python的优化手段是:第一次导入后就将模块名加载到内存了,后续的import语句仅是对已经加载到内存中的模块对象增加了一次引用,不会重新执行模块内的语句),如下 #test.py
import spam #只在第一次导入时才执行spam.py内代码,此处的显式效果是只打印一次'from the spam.py',当然其他的顶级代码也都被执行了,只不过没有显示效果.
import spam
import spam
import spam 执行结果:
from the spam.py
ps:我们可以从sys.module中找到当前已经加载的模块,sys.module是一个字典,内部包含模块名与模块对象的映射,该字典决定了导入模块时是否需要重新导入
2、在第一次导入模块时会做三件事,重复导入会直接引用内存中已经加载好的结果
1、为源文件(spam模块)创建新的名称空间,在spam中定义的函数和方法若是使用到了global(全局变量)时访问的就是这个名称空间
2、在新创建的命名空间中执行模块中包含的代码,见初始导入import spam
提示:导入模块时到底执行了什么?
In fact function definitions are also ‘statements’ that are
‘executed’; the execution of a module-level function definition
enters the function name in the module’s global symbol table.
事实上函数定义也是“被执行”的语句,模块级别函数定义的执行将函数名放
入模块全局名称空间表,用globals()可以查看3、创建名字spam来引用该命名空间
这个名字和变量名没什么区别,都是‘第一类的’,且使用spam.名字的方式
可以访问spam.py文件中定义的名字,spam.名字与test.py中的名字来自
两个完全不同的地方。
3、被导入模块有独立的名称空间
每个模块都是一个独立的名称空间,定义在这个中的函数,把这个模块的名称空间当做全局名称空间,这样我们在编写自己的模块时,就不用担心我们定义在自己模块中全局变量会在被导入时,与使用者的全局变量冲突
import spam
money=10
print(spam.money)
print(money) #结果如下 可以看出来两个相同的全局变量并没有冲突
from the spam.py
1000
10
测试1:money与spam.money不冲突
import spam
def read1():
print('++++++++++++++++')
spam.read1() #结果如下
from the spam.py
spam模块: 1000
测试2:read1与spam.read1不冲突
import spam
money=1
spam.change()
print(money) #结果如下
from the spam.py
1 #spam.py的change改成在执行下
def change():
global money
money=0
print('global模块',money) #结果如下
from the spam.py
global模块 0
1
测试3:执行spam.change()操作的全局变量money仍然时spam中的
4、为模块起别名
为已经导入的模块起别名的方式对编写可扩展的代码很有用
import spam as sm
print(sm.money)
#结果
from the spam.py
1000
有两种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 as reader
elif file_format == 'csv':
import csvreader as reader
data=reader.read_date(filename)
5、在一行导入多个模块
import sys,os,re
三、使用模块之from...import...
python之旅:模块与包的更多相关文章
- 二十五. Python基础(25)--模块和包
二十五. Python基础(25)--模块和包 ● 知识框架 ● 模块的属性__name__ # my_module.py def fun1(): print("Hello& ...
- Python中的模块与包
标准库的安装路径 在import模块的时候,python是通过系统路径找到这些模块的,我们可以将这些路径打印出来: >>> pprint.pprint(sys.path) ['', ...
- 【循序渐进学Python】10.模块和包
1.导入模块 任何Python程序都可以作为模块导入,只要Python解释器能找到我们定义的模块所在位置即可,一般来讲,在一个模块被导入时,Python解释器会按照下面的步骤进行搜索: 在当前所在目录 ...
- Python类、模块、包的区别
类 类的概念在许多语言中出现,很容易理解.它将数据和操作进行封装,以便将来的复用. 模块 模块,在Python可理解为对应于一个文件.在创建了一个脚本文件后,定义了某些函数和变量.你在其他需要这些功能 ...
- Python进阶之模块与包
模块 .note-content {font-family: "Helvetica Neue",Arial,"Hiragino Sans GB","S ...
- python之路模块与包
一.import加载的模块分为四个通用类别: 1 使用python编写的代码(.py文件) 2 已被编译为共享库或DLL的C或C++扩展 3 包好一组模块的包 4 使用C编写并链接到 ...
- 【Python实战】模块和包导入详解(import)
1.模块(module) 1.1 模块定义 通常模块为一个.py文件,其他可作为module的文件类型还有".pyo".".pyc".".pyd&qu ...
- python中的模块和包
模块 一 什么是模块 模块就是一组功能的集合体,可以通过导入模块来复用模块的功能. 比如我在同一个文件夹定义两个.py文件,分别命名为A.py和B.py,那么可以通过在A文件里通过import B来使 ...
- python之路--模块和包
一 . 模块 ⾸先,我们先看⼀个老⽣常谈的问题. 什么是模块. 模块就是⼀个包含了python定义和声明的⽂件, ⽂件名就是模块的名字加上.py后缀. 换句话说我们⽬前写的所有的py⽂件都可以看成是⼀ ...
- python之import模块及包的调用
模块概念 在Python中,一个.py文件就称之为一个模块(Module).使用模块组织代码,最大的好处是大大提高了代码的可维护性 模块一共三种:python标准库.第三方模块.应用程序自定义模块. ...
随机推荐
- 高可用OpenStack(Queen版)集群-12.Cinder计算节点
参考文档: Install-guide:https://docs.openstack.org/install-guide/ OpenStack High Availability Guide:http ...
- Final发布文案+美工
团队名称:探路者 1蔺依铭:http://www.cnblogs.com/linym762/(组长) 2张恩聚:http://www.cnblogs.com/zej87/ 3米赫:http://www ...
- Alpha版本BUG BASH
在本次软件开发的第一轮迭代中,我们团队遇到了很多问题.首先是和学长联系不上导致拿到项目前一版本的代码的时间延后了一个星期. 拿到代码后发现由于安装环境的问题代码无法移植.在这一阶段我们就耗费了大量的时 ...
- Mac OS10.10 openfire无法启动问题
1.我用的Java版本是Version 8 Update 51,验证方法可到这个网址下去验证http://www.java.com/zh_CN/download/installed.jsp 2.ope ...
- grunt入门讲解5:创建插件,安装Grunt以及常见问题
创建插件 创建插件主要有以下几个步骤: (1)通过 npm install -g grunt-init 命令安装 grunt-init .(2)通过 git clone git://github.co ...
- 用css 修改 谷歌浏览器自带的 滚动条样式
::-webkit-scrollbar { width: 0.5rem;}/* Track */ ::-webkit-scrollbar-track { -webkit-box-shadow: ins ...
- 第九周(11.11-11.17)----Beta版本发布140字评论
1.新蜂组: 俄罗斯方块:项目有良好的用户界面,在原版的基础上可以对用户分数进行排序,增加了显示下一个方块的功能.是个很有趣的小游戏. 2.天天向上组: 连连看:完成了基本功能,增加了消除时和鼠标点击 ...
- 【Leetcode】143. Reorder List
Question: Given a singly linked list L: L0→L1→…→Ln-1→Ln, reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… You ...
- Openresty+Lua+Redis灰度发布
灰度发布,简单来说,就是根据各种条件,让一部分用户使用旧版本,另一部分用户使用新版本.百度百科中解释:灰度发布是指在黑与白之间,能够平滑过渡的一种发布方式.AB test就是一种灰度发布方式,让一部分 ...
- Vue.js——60分钟browserify项目模板快速入门
概述 在之前的一系列vue.js文章,我们都是用传统模式引用vue.js以及其他的js文件的,这在开发时会产生一些问题. 首先,这限定了我们的开发模式是基于页面的,而不是基于组件的,组件的所有代码都直 ...