Python 进阶_模块 & 包
目录
模块的搜索路径和路径搜索
搜索路径
默认的模块搜索路径在 Python 解析器编译安装时被指定, 我们可以通过 sys 模块来查看和修改它:
In [4]: sys.path
Out[4]:
['',
'/usr/bin',
'/usr/lib/python2.7',
'/usr/lib/python2.7/plat-x86_64-linux-gnu',
'/usr/lib/python2.7/lib-tk',
'/usr/lib/python2.7/lib-old',
'/usr/lib/python2.7/lib-dynload',
'/usr/local/lib/python2.7/dist-packages',
'/opt/stack/keystone',
'/opt/stack/glance',
'/opt/stack/cinder',
'/opt/stack/nova',
'/opt/stack/horizon',
'/opt/stack/tempest',
'/opt/stack/oslo.vmware',
'/usr/lib/python2.7/dist-packages',
'/usr/lib/python2.7/dist-packages/IPython/extensions']
存在于搜索路径列表的路径下的模块就可以直接被 import 了.
我们还能够通过 sys.models 可以找到当前导入了那些模块和它来自萨满路径和地方.
NOTE: 这个路径每个人都不尽相同, 在安装 Openstack 项目时, 每一个项目的根目录都会加入到该目录列表中
命名空间和变量作用域的比较
命名空间: 是变量名(标识符)到实际对象的映射, 是一个字典. Python 的命名空间类型有 内建命名空间/全局命名空间/嵌套命名空间/局部命名空间.
Python 解析器启动时, 首先会加载 内建命名空间 , 该空间的变量名映射被包含在 __builtin__ 模块中, 我们可以通过 __builtin__.__dict__ 来查看其包含的变量字典, 主要包含了 ERROR/内建函数 等类型.
注意: __builtin__ 模块和 __builtins__ 模块的名称非常相似, 在标准的 Python 环境中 __builtins__ 含有 __builtin__ 内的所有变量名映射, 却别在于 __builtins__ 是可以被修改的, 用于创建一个 “沙盒” 环境, 但少有人用, 所以两者并不相等.
作用域: 变量名有效的区域定义. 指定了一个变量名在一个指定的区域内有效.
两者的区别: 作用域和命名空间非常相似, 一个作用域的创建伴随着新的命名空间的生成, 其一般是具有对应的关系. 所以往往命名空间中含有的变量名在对应的作用域中都是有效的. 但本质的区别是: 命名空间是纯粹意义上的变量名和对象的映射关系, 而作用域还指出了在代码中的那个物理位置(模块内/类内/函数类)可以访问到命名空间的变量名, 从而得到其映射的对象.
无限制的命名空间: Python 的一个特性在于我们可以动态的为一个函数对象添加变量, 这种变量也称之为实例属性. 所以 Python 的命名空间是无限制的.
In [9]: def func():
...: print "This is a func"
...:
In [10]: func.__dict__
Out[10]: {}
In [13]: func.name = 'JMilkFan'
In [14]: func.__dict__
Out[14]: {'name': 'JMilkFan'}
变量名的查找/覆盖
当我们 call 一个变量名时, Python 解析器的查找顺序如下:
1. 先从局部命名空间开始找, 如果找到了, 则引用变量名映射的对象. 若没有找到, 则进行下一步
2. 到嵌套命名空间找, 如果没有找到, 则进行下一步
3. 到全局命名空间找, 如果没有找到, 则进行下一步
4. 到内置命名空间找, 如果没有找到, 则进入下一步
从这个变量名查找算法可以看出, 当我们在代码物理位置定义了一个变量时, 这个变量就会添加到命名空间中. 而且这个命名空间为变量名的查找提供了清单. 更重要的一点是这个查找算法还有效的覆盖了外层作用域的同名变量. 局部作用域 覆盖 嵌套作用域 覆盖 全局作用域 覆盖 内置作用域.
导入模块
import 语句
import module1[, module2, ..., moduleN]
Python 允许一行导入多个模块, 但那这并不符合 PEP8 的编程标准, 所以建议使用多行导入的方式.
导入模块类型的顺序(中间已单空行隔开):
1. Python 标准库模块
2. Python 第三方模块
3. Python 自定义模块
NOTE: 模块的导入遵循作用域的原则, 在顶格导入的模块, 那么模块的作用域是全局的. 在函数或类内导入的模块, 其作用域就是局部或嵌套作用域.
from-import 语句
如果你希望从一个模块中导入指定属性, 或希望从一个 package 中导入一个模块, 都可以使用 form-import 语句.
from-import 语句也支持一行导入多个模块或属性, EG.
from package import (module1, module2, module3, ..., moduleN)
from-import 语句的好处在于: 针对性的导入可以提高效率和节省空间
NOTE: 我们一般建议导入到模块即可, 非特殊情况不要导入包或模块内的属性
扩展的 import 语句 as
也称之为别名, 模块之间也会经常出现同名的情况, 如果出现同一个模块中导入了两个或多个同名模块的情况, 那么应该为每个相同的模块取一个别名来有效区分. 除此之外, 如果模块的全称过长, 我们也可以为其取一个短小的别名. EG.
import module1 as module_one
from package import module1 as module_two
import Tkinter as tk
自动载入模块
Python 解析器在标准模式下启动会自动的导入一个模块, 例如 __bulitin__. 我们可以通过 sys.modules 来查看已经被导入到当前环境下模块字典, key 为模块名, value 为模块路径.
import sys
sys.modules.keys()
模块导入的特性
加载模块时执行文件
在导入模块时, 其顶格的代码(全局变量/类定义/函数定义…)会被执行, 所以不建议写太多的顶格代码, 应尽量多的将顶格代码收入函数或类体内.导入和加载模块是不一样的
一个模块可以被导入多次, 但正常情况下只能被加载一次. 当然除了手动加载之外. EG: 你需要在一个模块中导入 5 个模块, 其中之一为 sys 模块, 然后另外的 4 个模块也需要导入 sys 模块, 这种情况下, sys 模块只会被加载一次, 但却会被导入 5 次.导入到当前命名空间的变量
通过 from-import 导入到当前命名空间的模块变量是不需要通过句点标识符来调用的, 直接就可以引用. 但是不建议通过 from-import 来直接导入模块变量, 这样容易污染当前的命名空间, 可能导致覆盖一个已经存在的具有相同名字的对象.
模块内建函数
__import__()
格式:
__import__(module_name[, globals[, locals[, fromlist]]])
# globals 是全局命名空间的字典 ⇒ globals()
# locals 是局部命名空间的字典 ⇒ locals()
# fromlist 是 from-import 语句导入的变量名的列表 ⇒ []
当我们执行 import 语句的时候, 实际上是调用了 __import__() 内置函数, EG:
import sys
# 等效于
sys = __import__('sys')
globals() / locals() / reload()
- globals(): 返回调用者的全局命名空间的字典
locals(): 返回调用者的局部命名空间的字典
NOTE: 如果在全局命名空间调用上面两个内置函数, 那么两者返回的字典是相同的reload(): 重新导入一个已经被导入了的模块
NOTE: reload() 由两个使用限制- 模块必须全部被导入, 不能重载通过 from-import 来导入模块属性的模块
- 该模块必须是已经被导入了的, 才能被重载
模块的顶格代码在导入的时候会执行且仅执行一次, 再次导入的时候不会被执行, 如果希望再次执行的话, 可以使用 reload()
Package 包
模块是代码的组织形式, 包是模块的组织形式. 如果在一个目录中创建了 __init__.py 文件, 那么 Python 解析器会将该目录标识为一个包 Package.
NOTE: 我们一般在使用 import 语句的时候, 建议导入到模块级别, 不要导入模块属性, 也不要导入包.
__init__.py
__init__.py 文件是包的标识文件, 作为包的初始化模块, from-import 包下的模块会子包时, 需要用到该初始化模块, 所以现在如果一个包中没有该模块时, 会触发 ImportWarning 信息.
import package
如果我们不需要使用初始化模块__init__.py时. 该模块的内容为空, 如果我们需要使用该模块时, import packageName == import packageName._init_.
而且需要注意的是: 如果我们执行 from package import * 时, 会将该包下的所有模块和属性导入, 实际上这种做法是不科学的. 所以在包的初始化模块文件中有一个特殊属性 __all__ , __all__ 属性由一个模块名字组成的列表组成, 这个列表中包含了所有在执行全导入时应该被导入的模块和属性的名字.
Python 进阶_模块 & 包的更多相关文章
- Python进阶----pymysql模块的使用,单表查询
Python进阶----pymysql模块的使用,单表查询 一丶使用pymysql 1.下载pymysql包: pip3 install pymysql 2.编写代码 ...
- python进阶_浅谈面向对象进阶
python进阶_浅谈面向对象进阶 学了面向对象三大特性继承,多态,封装.今天我们看看面向对象的一些进阶内容,反射和一些类的内置函数. 一.isinstance和issubclass class F ...
- Python第八天 模块 包 全局变量和内置变量__name__ Python path
Python第八天 模块 包 全局变量和内置变量__name__ Python path 目录 Pycharm使用技巧(转载) Python第一天 安装 shell 文件 Pyt ...
- Python进阶(八)----模块,import , from import 和 `__name__`的使用
Python进阶(八)----模块,import , from import 和 __name__的使用 一丶模块的初识 #### 什么是模块: # 模块就是一个py文件(这个模块存放很多相似的功能, ...
- Python 进阶_生成器 & 生成器表达式
目录 目录 相关知识点 生成器 生成器 fab 的执行过程 生成器和迭代器的区别 生成器的优势 加强的生成器特性 生成器表达式 生成器表达式样例 小结 相关知识点 Python 进阶_迭代器 & ...
- Python进阶之模块与包
模块 .note-content {font-family: "Helvetica Neue",Arial,"Hiragino Sans GB","S ...
- Python进阶之模块
在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很 ...
- Python进阶03 模块
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们之前看到了函数和对象.从本质上来说,它们都是为了更好的组织已经有的程序,以方便 ...
- python语法_模块
方便调用的分组函数文件,一个py模块就是一个模块,模块分三类 python标准库 第三方模块 应程序自定义模块 模块的掉用: 可以把多个功能(函数)包含在一个模块文件里,调用时直接使用import 就 ...
随机推荐
- Day7-----Python的序列类(有子类:元组类,列表类)
序列类型 1.基本介绍: 序列类型是一种基类类型 ,既然被称为那就肯定是有道理的,关于序列 它有 正向 和 反向 两种序号,正向序号从零开始,反向序号从负一开始 a = '例如这个字符串' ...
- JavaScript的变量作用域
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- JS中的匿名函数、回调函数、匿名回调函数
工欲善其事必先利其器 在学习JavaScript设计模式一书时,遇到了“匿名回调函数”这个概念,有点疑惑,查找了些资料重新看了下函数的相关知识点之后,对这个概念有了认识.九层之台,起于垒土.在熟悉这一 ...
- centos7 利用mailx发送邮件
当需要服务器定时发送邮件到自己邮箱时,一个邮件服务就很重要了,以下主要是mailx的实现,主要是利用 1.安装mailx 1 yum install mailx -y 2.使用到的配置文件只有一个 ...
- openstack stein部署手册 2. 基础应用
1. chrony # 安装程序包 yum install -y chrony # 变更配置文件 /etc/chrony.conf 增加 server 192.168.123.200 iburst # ...
- 机器学习-线性回归(基于R语言)
基本概念 利用线性的方法,模拟因变量与一个或多个自变量之间的关系.自变量是模型输入值,因变量是模型基于自变量的输出值. 因变量是自变量线性叠加和的结果. 线性回归模型背后的逻辑——最小二乘法计算线性系 ...
- javaweb各种框架组合案例(五):springboot+mybatis+generator
一.介绍 1.springboot是spring项目的总结+整合 当我们搭smm,ssh,ssjdbc等组合框架时,各种配置不胜其烦,不仅是配置问题,在添加各种依赖时也是让人头疼,关键有些jar包之间 ...
- Django--Auth模块使用
1.Auth模块介绍 1.1 Auth模块是Django自带的用户认证模块,用于处理用户账户.群组.许可和基于cookie的用户回话 Django的认证系统主要包括下面几个部分 1.用户 2.许可 3 ...
- mysql 联合表查询从表即使有索引依然ALL的一个原因
那就是主表和从表的关联字段的编码方式不一样!!! 晕啊,折腾了半天才发现,可能是不知道啥时候mysql更改主体编码方式了,结果导致后来新建的表的关联字段和之前的主表的字段的编码方式不一样 改成一样的编 ...
- wait与sleep区别?
wait与sleep区别? 对于sleep()方法,该方法是属于Thread类中的.而wait()方法,则是属于Object类中的. sleep()方法导致了程序暂停执行指定的时间,让出cpu给其他线 ...