1. 概念

 模块是最高级别的程序组织单元,它将程序文件和数据封装起来以便重用。实际上,模块往往对应Python文件,每一个文件都是一个模块,并且模块导入其他模块之后就可以使用导入模块定义的变量,模块和类实际上就是一个重要的命名空间。

2. 模块的导入

  • import:使导入者以一个整体获取一个模块,import b可能对应的文件:b.py, b.pyc, b.pyo, 模块包b目录,b.so/b.dll, Python内置库,b.zip文件组件(导入时自动给解压缩),内存内映射(frozen的可执行文件)。
  • from:允许导入者从一个模块文件中获取特定的变量名。
  • imp.reload:在不中止Python程序的情况下,提供了一种重新载入模块文件代码的方法。

import和from是赋值语句:import将整个模块对象赋值给一个变量名,from将一个或多个变量名赋值给另一个模块中同名的对象,from复制的变量名会变成对共享对象的引用。

small.py:

  x = 1

  y = [1,2]

from small import x,y # 从small里面拷贝两个名字

x = 42 # 改变我的x值

y[0] = 42  # 这是修改了一个对象,而不是变量名

import small

print(small.x) # 仍然为值1,获取small模块中的x,不是我的x

print(small.y) # [42, 2], y[0]被修改为42了。

from module import name1, name2概念上与下面的代码一样。

import module

name1 = module.name1

name2 = module.name2

del module

3. 模块的作用

  • 代码重用:模块文件中的代码是永久的,可任意多次重新载入、运行。
  • 系统命名空间的划分:模块是Python总最高级别的程序组织单元。
  • 实现共享服务和数据:全局对象数据统一定义,多个代码文件间实现共享。

4. import工作原理

导入(import)是运行时的运算,程序第一次导入指定文件时,执行三个步骤:

  • 查找:找到模块文件。程序所在目录,PYTHONPATH, 标准链接库目录,任何.pth文件的内容(sites-packages)(这是个内容构成:sys.path列表)
  • 编译:文件编译成位码(需要时):.pyc, .pyo文件
  • 执行:执行模块的代码来创建所定义的对象

以上操作,只有在第一次导入文件才需要,以后的导入操作则直接读取内存中的数据,导入的模块存放在sys.modules中.

5. 模块包

$ mkdir packages/sound/{effects,filters,utils} -p
$ cd packages/ 1. 存在sound/__init__.py文件
$ python
>>> from sound import * # 没有报错,此时没有__init__.py文件
>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__'] # 显示的列表中没有该sound包相关的信息 $ cat > sound/__init__.py
print("in sound.__init__.py")
__all__ = ['effects','filters','utils']
$ python
>>> from sound import *
in sound.__init__.py
>>> dir()
[..., 'effects', 'filters', 'utils'] # 多出了__all__里面配置的变量
>>> dir(effects) # 注意effects没有加引号,也就是可以直接通过effects访问,effects下当前没有__init__.py文件 2. 存在sound/__init__.py, test1.py文件
$ cat > sound/test1.py
print("in sound.test1.py") def test():
print("in sound.test1.py:test()")
$ python
>>> from sound import * # 导入所有,但是不存在test1
in sound.__init__.py
>>> test1.test()
>>> dir(test1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'test1' is not defined 原因:test1 没有加入到 __all__中
$ cat > sound/__init__.py
print("in sound.__init__.py")
__all__ = ['effects','filters','utils','test1'] # 加入test1
$ python
>>> from sound import * # 导入所有,包含test1
in sound.__init__.py
>>> test1.test()
>>> dir(test1) $ cat > sound/__init__.py # 恢复到不含有test1
print("in sound.__init__.py")
__all__ = ['effects','filters','utils'] # 不含有test1
$ python
>>> import sound.test1 # 单独导入test1
in sound.__init__.py
in sound.test1.py
>>> dir()
[..., 'sound'] # 全局有sound
>>> dir(sound)
[..., 'test1'] # sound内有test1,但是没有effects等定义在__all__中的模块
>>> sound.test1.test() # 可以访问
in sound.test1.py:test() $ python
>>> from sound import test1
in sound.__init__.py
in sound.test1.py
>>> dir()
[..., 'test1'] # 有test1,不需要在__all__定义,访问了sound/__init__.py文件,没有sound
>>> dir(sound) # 出错
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'sound' is not defined >>> test1.test() # 可以访问
in sound.test1.py:test() $ python
>>> import sound # 无法访问test1
in sound.__init__.py
>>> dir()
[..., 'sound']
>>> dir(sound) # 没有test1, 没有effects(定义在__all__变量中)
>>> sound.test1.test() # 不可以访问
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'sound.test1' is not defined $ cat > sound/__init__.py
print("in sound.__init__.py")
__all__ = ['effects','filters','utils']
from . import test1
>>> import sound # 可以访问test1
in sound.__init__.py
in sound.test1.py
>>> dir()
[..., 'sound'] # 有sound
>>> dir(sound)
[..., 'test1'] # 有test,没有effects(定义在__all__变量中)
>>> sound.test1.test() # 可以访问
in sound.test1.py:test()

总结:
1. import sound:

  执行sound/__init__.py,并且解析__all__变量(如果存在的元素不存在,会抛出AttributeError异常)
  a) 可以访问sound.* (*必须是在__init__.py中有定义的变量,或者通过from 语句导入的模块)
    from . import test1: 可以访问sound.test1
    import test1: 此时或提示无法导入模块(sys.path找不到test1.py文件)
  b) 不会展开__all__变量,即无法访问sound.effects(effects内是否存在__init__.py,效果一致)
2. from sound import *:
  a) 执行sound/__init__.py,并且解析__all__变量(如果存在的元素不存在,会抛出AttributeError异常)
  b) 展开__all__:可以访问effects.xxx
3. from sound import test1:

  执行sound/__init__.py,执行sound/test1.py,不需要在sound/__init__.py文件中做任何配置,即可访问到sound.test1.py (只需要sound/__init__.py文件存在)

扩展解释:

sound/
    __init__.py
    test1.py (test()) # e_test1.py要访问该方法,在e_test1.py文件中需要明确import该模块
    effects/
        __init__.py
        e_test1.py (e_test()) # 要访问test1.py提供的方法,需要明确的import test1模块

from sound import effects.e_test1:错误,语法不支持(import后不能带.)
from sound.effects import e_test1:

  • 依次调用:sound/__init__.py (不展开__all__) -> sound/effects/__init__.py(不展开__all__) -> sound/effects/e_test1.py
  • 然后将e_test1 = """e_test1.py中的全部Python代码"""
  • 如果sound/__ini__.py内有from . import test1.py #test1.py提供的test方法,e_test1.py内还是无法访问的,需要在e_test1.py文件内单独import(但是在真实执行时,在解析sound/__init__.py文件的时候已经解析过了,不会再次解析。

[TimLinux] Python 模块的更多相关文章

  1. 使用C/C++写Python模块

    最近看开源项目时学习了一下用C/C++写python模块,顺便把学习进行一下总结,废话少说直接开始: 环境:windows.python2.78.VS2010或MingW 1 创建VC工程 (1) 打 ...

  2. Python模块之configpraser

    Python模块之configpraser   一. configpraser简介 用于处理特定格式的文件,其本质还是利用open来操作文件. 配置文件的格式: 使用"[]"内包含 ...

  3. Python模块之"prettytable"

    Python模块之"prettytable" 摘要: Python通过prettytable模块可以将输出内容如表格方式整齐的输出.(对于用Python操作数据库会经常用到) 1. ...

  4. python 学习第五天,python模块

    一,Python的模块导入 1,在写python的模块导入之前,先来讲一些Python中的概念性的问题 (1)模块:用来从逻辑上组织Python代码(变量,函数,类,逻辑:实现一个功能),本质是.py ...

  5. windows下安装python模块

    如何在windows下安装python模块 1. 官网下载安装包,比如(pip : https://pypi.python.org/pypi/pip#downloads) pip-9.0.1.tar. ...

  6. 安装第三方Python模块,增加InfoPi的健壮性

    这3个第三方Python模块是可选的,不安装的话InfoPi也可以运行. 但是如果安装了,会增加InfoPi的健壮性. 目录 1.cchardet    自动检测文本编码 2.lxml    用于解析 ...

  7. Python基础篇【第5篇】: Python模块基础(一)

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

  8. python 模块加载

    python 模块加载 本文主要介绍python模块加载的过程. module的组成 所有的module都是由对象和对象之间的关系组成. type和object python中所有的东西都是对象,分为 ...

  9. pycharm安装python模块

    这个工具真的好好,真的很喜欢,它很方便,很漂亮,各种好 pycharm安装python模块:file-setting-搜索project inte OK

随机推荐

  1. Linux系统重启Oracle-12c步骤

    Linux系统重启Oracle-12c步骤 1. 使用oracle用户登录: [root@Oracle-12c /]# su – oracle 2. 登录oracle登陆管理员账号: [oracle@ ...

  2. php 微信jssdk 微信分享一直报config:fail,Error: invalid signature(签名生成是一致的)

    php 微信jssdk 微信分享一直报config:fail,Error: invalid signature(签名生成是一致的) 里面url必须是当前的url比方说在A地址 请求获取jssdk参数 ...

  3. SSE图像算法优化系列三十:GIMP中的Noise Reduction算法原理及快速实现。

    GIMP源代码链接:https://gitlab.gnome.org/GNOME/gimp/-/archive/master/gimp-master.zip GEGL相关代码链接:https://gi ...

  4. idea 常用功能

      Ctrl + E:打开最近文件   双击 Shift:按文件名查找文件   Ctrl + Shift + F:全局搜索   Alt + ~(数字 1 左边的键):commit.push 代码   ...

  5. java 深拷贝与浅拷贝

    yls 2019年11月07日 拷贝分为引用拷贝和对象拷贝 深拷贝和浅拷贝都属于对象拷贝 浅拷贝:通过Object默认的clone方法实现 实现Cloneable接口 public class She ...

  6. [多态] java笔记之多态性

    1.多态,说的是对象,说的不是类. 2. 3.多态 = polymorphism 4. 调用如下: 5. 6.口诀: 7.对象的向上转型: 8.对象的向下转型: 9.下面这个异常叫做ClassCast ...

  7. PHP产生不重复随机数的5个方法总结

    无论是Web应用,还是WAP或者移动应用,随机数都有其用武之地.在最近接触的几个小项目中,我也经常需要和随机数或者随机数组打交道,所以,对于PHP如何产生不重复随机数常用的几种方法小结一下 无论是We ...

  8. 让块元素在div中水平居中,并且垂直居中的五种方法

    在写代码前,先做下准备工作,写两个div,设置下div的大小,把小的div放在大的div里面.可以给小的div设置下颜色,方便观看. 方法一:写一个伪元素,将它设置为行内块元素,高度与父元素相同,写一 ...

  9. App稳定性测试Monkey

    1.$ adb shell monkey <event-count>                <event-count>是随机发送事件数 例:adb shell monk ...

  10. salesforce lightning零基础学习(十五) 公用组件之 获取表字段的Picklist(多语言)

    此篇参考:salesforce 零基础学习(六十二)获取sObject中类型为Picklist的field values(含record type) 我们在lightning中在前台会经常碰到获取pi ...