目录

模块的搜索路径和路径搜索

搜索路径

默认的模块搜索路径在 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() 由两个使用限制

    1. 模块必须全部被导入, 不能重载通过 from-import 来导入模块属性的模块
    2. 该模块必须是已经被导入了的, 才能被重载

      模块的顶格代码在导入的时候会执行且仅执行一次, 再次导入的时候不会被执行, 如果希望再次执行的话, 可以使用 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 进阶_模块 & 包的更多相关文章

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

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

  2. python进阶_浅谈面向对象进阶

    python进阶_浅谈面向对象进阶 学了面向对象三大特性继承,多态,封装.今天我们看看面向对象的一些进阶内容,反射和一些类的内置函数. 一.isinstance和issubclass  class F ...

  3. Python第八天 模块 包 全局变量和内置变量__name__ Python path

    Python第八天  模块   包   全局变量和内置变量__name__    Python path 目录 Pycharm使用技巧(转载) Python第一天  安装  shell  文件 Pyt ...

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

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

  5. Python 进阶_生成器 & 生成器表达式

    目录 目录 相关知识点 生成器 生成器 fab 的执行过程 生成器和迭代器的区别 生成器的优势 加强的生成器特性 生成器表达式 生成器表达式样例 小结 相关知识点 Python 进阶_迭代器 & ...

  6. Python进阶之模块与包

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

  7. Python进阶之模块

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

  8. Python进阶03 模块

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们之前看到了函数和对象.从本质上来说,它们都是为了更好的组织已经有的程序,以方便 ...

  9. python语法_模块

    方便调用的分组函数文件,一个py模块就是一个模块,模块分三类 python标准库 第三方模块 应程序自定义模块 模块的掉用: 可以把多个功能(函数)包含在一个模块文件里,调用时直接使用import 就 ...

随机推荐

  1. ajax基础--基本概念

    1.Ajax的全称: Asynchronous Javascript And XML,就是使用is代码获取服务器数据 局部异步刷新 IP地址:用来标识查找某一台计算机 域名:ip地址太难记了,使用域名 ...

  2. python的运算符和while循环

    一.运算符 计算机可以进行的运算有很多种,不只是加减乘除,它和我们人脑一样,也可以做很多运算. 种类:算术运算,比较运算,逻辑运算,赋值运算,成员运算,身份运算,位运算,今天我们先了解前四个. 算术运 ...

  3. 《JAVA设计模式》之模板模式(Template)

    在阎宏博士的<JAVA与模式>一书中开头是这样描述模板方法(Template Method)模式的: 模板方法模式是类的行为模式.准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式 ...

  4. mysql时间增加一年

    update siteserver_content_57 set AddDate=DATE_ADD(AddDate,INTERVAL 2 year),LastHitsDate=DATE_ADD(Las ...

  5. redis 哨兵配置文件解读sentinel.conf

    # Example sentinel.conf # port <sentinel-port>port 8001 # 守护进程模式daemonize yes # 指明日志文件名logfile ...

  6. python学习二十一天文件可读,可写,可执行的操作

    文件无非是可读,可写,可执行的操作,分别对应的模式 r ,w,x,只读模式,只写模式,只执行模式,a模式为追加模式,实际也是写操作模式,r+,w+,a+ 可读写模式,下面详细说模式的用法 1,文件的模 ...

  7. android 好的源码链接

    1.自定义表情键盘:https://github.com/w446108264/XhsEmoticonsKeyboard 2.底部导航栏https://github.com/Ashok-Varma/B ...

  8. elasticsearch 深入 —— 相关度控制

    控制相关度 处理结构化数据(比如:时间.数字.字符串.枚举)的数据库, 只需检查文档(或关系数据库里的行)是否与查询匹配. 布尔的是/非匹配是全文搜索的基础,但不止如此,我们还要知道每个文档与查询的相 ...

  9. rmdir -删除空目录

    总览 rmdir[options]directory... POSIX 选项: [-p] GNU 选项(缩写): [-p] [--ignore-fail-on-non-empty] [--help] ...

  10. Cent OS 7 VNC 安装

    关闭防火墙 关闭selinux 挂载光盘到本地 #yum install tigervnc-server -y #cp /lib/systemd/system/vncserver@.service / ...