之前两天我们介绍了一些比较常用的模块,而我也说过会讲解什么是模块,今天我们就来分析分析模块和包,模块我们现阶段使用还可以而包的话现阶段我们基本很少会用到包,学的不是很清楚也没关系这些东西都是用的多了也就慢慢熟悉了。

本篇导航:

一、模块

在前面的几个章节中我们脚本上是用 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):模块和包的更多相关文章

  1. Python进阶之模块与包

    模块 .note-content {font-family: "Helvetica Neue",Arial,"Hiragino Sans GB","S ...

  2. Python进阶----pymysql模块的使用,单表查询

    Python进阶----pymysql模块的使用,单表查询 一丶使用pymysql ​   ​   1.下载pymysql包: pip3 install pymysql ​​   ​   2.编写代码 ...

  3. 二十五. Python基础(25)--模块和包

    二十五. Python基础(25)--模块和包 ● 知识框架   ● 模块的属性__name__ # my_module.py   def fun1():     print("Hello& ...

  4. Python进阶(八)----模块,import , from import 和 `__name__`的使用

    Python进阶(八)----模块,import , from import 和 __name__的使用 一丶模块的初识 #### 什么是模块: # 模块就是一个py文件(这个模块存放很多相似的功能, ...

  5. Python 进阶_模块 & 包

    目录 目录 模块的搜索路径和路径搜索 搜索路径 命名空间和变量作用域的比较 变量名的查找覆盖 导入模块 import 语句 from-import 语句 扩展的 import 语句 as 自动载入模块 ...

  6. Python进阶之模块

    在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很 ...

  7. python中的模块及包及软件目录结构规范

    知识内容: 1.模块的定义与分类 2.模块的导入 3.模块与包 4.不同目录下的模块调用 一.模块的定义与分类 1.什么是模块 模块就是实现了某个功能的代码集合,模块是由一大堆代码构成的 类似于函数式 ...

  8. Python中的模块与包

    标准库的安装路径 在import模块的时候,python是通过系统路径找到这些模块的,我们可以将这些路径打印出来: >>> pprint.pprint(sys.path) ['', ...

  9. 【循序渐进学Python】10.模块和包

    1.导入模块 任何Python程序都可以作为模块导入,只要Python解释器能找到我们定义的模块所在位置即可,一般来讲,在一个模块被导入时,Python解释器会按照下面的步骤进行搜索: 在当前所在目录 ...

  10. Python类、模块、包的区别

    类 类的概念在许多语言中出现,很容易理解.它将数据和操作进行封装,以便将来的复用. 模块 模块,在Python可理解为对应于一个文件.在创建了一个脚本文件后,定义了某些函数和变量.你在其他需要这些功能 ...

随机推荐

  1. css3实现可以计算的自适应布局——calc()

    开始我们需要先了解什么是calc() ,calc()是一个CSS函数,你可以使用calc()给元素的margin.pading.width等属性设置 而且你还可以在一个calc()内部嵌套另一个cal ...

  2. AospExtended K3 Note最新官方版 Android7.1.2 极速 省电 流畅 Galaxy XIAOMI Moto Lenovo Coolpad 均支持

    AospExtended 最新官方版 Android7.1.2 极速 省电 流畅 Galaxy  XIAOMI Moto  Lenovo  Coolpad  均支持 之前用过1629开发版等,体验了很 ...

  3. 3.ubuntu如何安装搜狗输入法

    1.http://blog.csdn.net/qq_21792169/article/details/53152700 2.http://jingyan.baidu.com/article/54b6b ...

  4. MyBatis源码解析【3】生命周期

    经过之前的项目构建,我们已经得到了一个可以使用的最基本的项目. 其中已经包括整个执行的过程.但是我们在完成之后也遇到了很多问题,我们就要慢慢的一步步解决这些问题. 讲道理,今天我们其实应该直接开始看源 ...

  5. 什么是Hadoop

    配上官方介绍 What Is Apache Hadoop?    The Apache™ Hadoop® project develops open-source software for relia ...

  6. 浅入深出之Java集合框架(中)

    Java中的集合框架(中) 由于Java中的集合框架的内容比较多,在这里分为三个部分介绍Java的集合框架,内容是从浅到深,如果已经有java基础的小伙伴可以直接跳到<浅入深出之Java集合框架 ...

  7. (cljs/run-at (JSVM. :all) "细说函数")

    前言  作为一门函数式编程语言,深入了解函数的定义和使用自然是十分重要的事情,下面我们一起来学习吧! 3种基础定义方法 defn 定义语法 (defn name [params*] exprs*) 示 ...

  8. JavaScript第三课 (循环)

    循环语句       !如果至少需要执行一次循环体,就用do … while语句,一般情况下用while语句就可以了. while 语法:一直读取循环到条件为假时停止循环. while(条件) { 语 ...

  9. mysql主从复制原理探索

    上一篇文章里面,讲到了遇到mysql主从延迟的坑,对于这次的坑多说两句,以前也看过这样的例子,也知道不能够写完之后马上更新,但是真正开发的时候还是没有注意到这一点,道理大家都懂,但是还是会犯错,只有等 ...

  10. 用Left join代替not in

    很多人都知道 在各种数据库里面 not in 的效率极其低下.例如 select * from a where a.id not in ( select id from b ) 我们假如a表有 10万 ...