模块

Python核心编程 [第十二章]

模块是用来组织 Python 代码的方法,而包则是用来组织模块的

0x00什么是模块

  • 一些有一定联系的代码段,可能是包含一个数据成员和方法的类,也可能是一组相关但彼此独立的操作函数。这些代码是共享的。

0x01模块和文件

  • 文件是物理层上组织模块的方法,文件被看作一个独立模块,一个模块也可以被看作是一个文件。在 Pthon 中导入的是模块或模块属性。
模块命名空间
  • 一个命名空间就是一个从名称到对象的关系映射集合。模块命名时他们的属性名称中的一个重要部分。命名空间唯一,通过句点属性表示指定各自名称空间----防止了命名冲突。
搜索路径和路径搜索
  • 在文件系统“预定义区域”中查找 mymodule.py 文件(如果你导入 mymodule 的话)。这些预定义区域只不过是你的 Python 搜索路径的机和。搜索路径是指查找某个文件的[操作],路径搜索是指查找一组[目录]。如果解释器告诉你无法访问请求模块,可能是因为模块不在搜索路径里,从而导致路径搜索失败。
  • 默认搜索路径(在编译或安装时指定),可以在 shell 或命令行PYTHONPATH 环境变量修改。可以调用 sys.path(类型:列表) 查看,不同操作系统一般搜索路径不同。可以用 sys.path.append(’/xxx/xxx/xxx’) 添加搜索路径也可以使用 insert() 方法添加。
  • 如果一个模块有很多拷贝,解释器会沿搜索路径顺序找到第一个模块,sys.modules(类型:字典)可以查找当前导入了那些模块和它们来自什么地方。

0x02命名空间

  • 名称空间时名称到对象的映射。向名称空间添加名称的操作涉及绑定标识到指定对象的操作,改变一个名字的绑定叫重新绑定,删除一个名字叫解除绑定。
  • 在执行期间有两个或三个活动的名称空间,分别是局部名称空间,全局名称空间和内建名称空间,局部名称空间在执行期间时不断变化的,所以说“两个或三个”。从名称空间中访问这些名字依赖于它们的加载顺序或时系统加载这些名称空间的顺序。
  • Python搜先加载内建名称空间。它由 __builtins __ 模块中的名字构成。随后加载执行模块的全局命名空间,他会在模块开始执行后变为活动命名空间。
  • __builtins __ 和 __builtin __ ,__builtins __ 模块包含内建名称空间中内建名字的集合,其中大多数来自 __builtin __ ,__builtin __ 模块包含内建函数,异常以及其他属性。__builtins __ 包含 __builtin __ 的所有名字。
  • 在执行期间调用了一个函数,将会创建出第三个名称空间,即局部名称空间。可以通过 globals() 和 locals() 内建函数并判断属于哪一个名称空间。
名称空间与变量作用域比较
  • 名称空间和变量作用域的关系。
    名称空间和变量作用域的关系
  • 所有局部名称空间的名称都在局部作用范围内,局部作用范围以外的所有名称都在全局通范围内,局部名称空间作用域变化,全局名称空间时不变的。
名称查找、确定作用域、覆盖
  • 确定作用域的规则,进行名称查询。访问一个属性时,解释器必须在三个名称空间中的一个找到它,在局部查找再在全局查找最后在内建查找。
  • 覆盖影响,先找到的命名空间中的变量的值会覆盖后变名称空间中变量的值。
无限制的名称空间
  • Pthon 可以在任何需要放置数据的地方获得一个名称空间,在任何时候都可以给函数添加属性。
def foo():
	pass
foo.__doc__ = 'Oops'
foo.version = 0.2
class MyClass(object):
	pass
bag = MyClass
bag.x = 1   #(x、y 称为实例的属性)
bag.y = 2

0x03导入模块

import 语句
###多行导入
import module1
import module2

###单行导入
import module1,module2 .... moduleN

###推荐导入顺序
#Python标准库模块
#Python第三方库模块
#Python自定义模块
#使用一个空行分割这三类模块导入语句
  • 执行器执行到这条语句,如果在搜索路径中找到了指定模块,就会加载。该过程遵循作用域原则,如果在一个模块的顶层导入,那么它的作用域就是全局,如果在函数中导入,那么作用域是局部。如果第一次导入,它将被加载并执行。所以应该把尽可能多的代码封装到函数。只把函数和模块定义放到模块的顶层是良好的模块编程习惯。
form-import 语句
#导入指定模块的属性
from module import name1,name2 ..... nameN
多行导入
#导入多行导致换行时可以使用,不推荐使用 from module import *
form module import (a,b,c,d .... end)
扩展的 import 语句(as)
import Module
from Mi import attribute
--->
import Module as M
from Mi import attribute as a

0x04导入模块属性

载入时执行模块
  • 加载模块会导致这个模块被“执行”。也就是被导入模块的顶层代码将直接被执行。这通常包括设定全局变量以及类和函数的声明。如果有检查 name 的操作,那么它也会被执行。
导入(import)和加载(load)
  • 一个模块只被加载一次,无论导入多少次。加载只在第一次导入时发生。
导入到当前命名空间的名称
  • 调用 from-import 可以把名字导入当前的命名空间里去,这就意味着你不需要使用属性/句点属性表示来访问模块的标识符。
  • from module import *,因为它“污染”当前名称空间,很可能覆盖当前名称空间中现有的名字。在目标模块属性非常多和交互解释器下推荐使用此类编程风格。
被导入到导入者作用域的名字
  • 只从模块导入名字的另一个副作用是那些名字称为局部空间的一部分。这可能导致覆盖一个已经存在的具有相同名字的队形。而且堆这些变量的改变之影响它的局部拷贝而不是导致所导入模块的原始名称空间。也就是说,绑定只是局部而不是整个名称空间。
关于__future__
  • 可以用 from __future __ import new 导入可以导入新特性。
警告框架
  • 警告用户不要使用一个即将改变或不支持的操作,这个框架的另一个部分是一些警告异常类机和。Warning 直接从 Exception 继承,作为所有警告的基类,这个警告包括,User Warning,Deprecation Warning,Syntax Warning 和 Runtime Warning。另一个组件时警告过滤器,警告默认的输出显示到 sys.stderr。
从ZIP文件中导入模块
  • Python 加入了从 ZIP 归档文件导入模块的功能,导入时会把 ZIP当目录处理,在文件中搜索模块。

0x05模块内建函数

__import __()
  • 它作为实际上导入模块的函数,import语句调用 __import __()函数完成它的工作。提供这个函数是为了让有特殊需要的用户覆盖它,实现自定义的导入算法。
globals() 和 locals()
  • 分别返回调用者全局和局部名称空间的字典。在一个函数内部,局部名称空间代表在函数
reload()

0x06包

  • 包是一个有层次的文件目录结构,它定义了一个由模块和子包组成的 Python 应用程序执行环境。
目录结构
  • __init __.py 文件,这些是初始化模块,from import 语句导入子包时需要用到它。如果没有用到,它们可以是空文件。程序员经常忘记为它们的包目录加入 __init __.py,pyhon2.5 开始,这将会导致一个 ImportWarning 消息。
使用 from import 导入包
  • from package.module import * 这样导入哪些文件取决于操作系统 的文件系统。所以我们在 __init __.py 中加入 __all __变量。该变量包含执行这样的语句时应该导入的模块的名字,它由一个模块名字符串列表组成。
  • 绝对导入:很多情况下导入子包会导致和真正的标准库模块发生冲突。包模块会把名字相同的保准库模块隐藏掉,因为它首先在包内执行相对导入,隐藏掉标准库模块。所以,所有的导入现在都被认为是绝对的,也就是说这些名字必须通过 Python 路径来访问。

0x07模块的其他特性

自动载入的模块
  • 当 Python 解释器在标准模式下启动时,一些模块会被解释器自动导入,用于系统相关操作。唯一一个影响你的是 __builtin__ 模块,它会正常地被载入,这和 __builtins__ 模块相同。
  • sys.modules 变量包含一个由当前载入到解释器的模块组成的字典,模块名作为键,它们的位置为值。
阻止属性导入
  • 如果你不想让某个模块属性被 “from module import *” 导入,那么你可以给你想要导入的属性名称上加一个下划线 (_) 。如果你导入了整个模块或是你显示的导入某个模块属性(例如 import foo._bar),这个给隐藏数据的方法就不起作用了。
源代码编码
  • 在 Python 模块头部加入一个额外的编码指示说明就可以让导入者使用指定的编码解析你的模块。

    # 例如:
    
      # !/usr/bin/evn/ python
      # -*-codingL UTF-8 -*-
    
导入循环
  • 一种在大项目可能出现的问题,详见原书12.8.5
模块可执行
  • 有很多方法可以执行 Python 模块,例如:通过命令行、shell、execfile、导入模块、解释器的 -m 选项等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值