https://realpython.com/python-modules-packages/

在软件开发中,一个module是具有一些相关功能的软件集合,比如,当你在开发一个游戏时,可能会有一个模块负责game logic,而另一个module负责在屏幕上绘制对应的界面。每个module是一个不同的文件,可以单独编辑

modules

python中每一个单独的.py文件就是一个module,模块的名称就是文件的名称。一个module可以有一组函数,类或者变量。比如,上面说道的游戏开发中,可能会有两个文件组成的两个module:

  1. # game.py
  2. # import the draw module
  3. import draw
  4.  
  5. def play_game():
  6. ...
  7.  
  8. def main():
  9. result = play_game()
  10. draw.draw_game(result)
  11.  
  12. # this means that if this script is executed, then
  13. # main() will be executed
  14. if __name__ == '__main__':
  15. main()

在上面的game模块中,我们定义了play_game函数,它将使用定义在draw模块中的draw_game函数。而draw模块中实现draw_game对应的逻辑。

下面我们看看draw 模块长的样子:

  1. # draw.py
  2.  
  3. def draw_game():
  4. ...
  5.  
  6. def clear_screen(screen):
  7. ...

在本例子中game module通过import draw来加载draw模块,而这将赋能game模块引用draw模块中实现的函数或者类。为了使用draw模块中的draw_game,我们需要通过dot点操作符告知game块draw_game是哪个模块中的实现。

当import draw这个directive被执行时,python解释器将从game.py文件所在目录开始寻找draw.py文件,如果没有找到,python解释器将继续在built-in内置模块中寻找。

你可能注意到当导入一个module时,将会有一个.pyc文件出现,这个文件是一个编译过的Python文件。python解释器将module文件编译成python的byte code以便不用每次Import时都需要重新解析他。如果已经有了.pyc文件存在,则直接加载draw.pyc文件,这个过程对于用户来说是透明的。

importing module objects到当前的命名空间namespace

我们可以通过from及import命令将对应模块的函数加载到主脚本所在的命名空间中:

  1. # game.py
  2. # import the draw module
  3. from draw import draw_game
  4.  
  5. def main():
  6. result = play_game()
  7. draw_game(result)

通过上面的from, import后我们就不用再使用prefixmodule.function的方式来引用,而只需要function了,因为function已经存在于主脚本的命名空间里面了!

import all objects from module

  1. # game.py
  2. # import the draw module
  3. from draw import *
  4.  
  5. def main():
  6. result = play_game()
  7. draw_game(result)

自定义加载后的命名

  1. # game.py
  2. # import the draw module
  3. if visual_mode:
  4. # in visual mode, we draw using graphics
  5. import draw_visual as draw
  6. else:
  7. # in textual mode, we print out text
  8. import draw_textual as draw
  9.  
  10. def main():
  11. result = play_game()
  12. # this can either be visual or textual depending on visual_mode
  13. draw.draw_game(result)

上面的例子中,使用as关键字,以及条件加载使得不同的module中定义的函数使用同一个名称draw

module initialization

当一个module首次被加载时,对应module的代码将会执行一次以便初始化。如果其他的模块再次加载同一个module,则不会再重复加载!因此,module中的局部变量就像一个singleton一样,因为他们仅会初始化一次。

  1. # draw.py
  2.  
  3. def draw_game():
  4. # when clearing the screen we can use the main screen object initialized in this module
  5. clear_screen(main_screen)
  6. ...
  7.  
  8. def clear_screen(screen):
  9. ...
  10.  
  11. class Screen():
  12. ...
  13.  
  14. # initialize main_screen as a singleton
  15. main_screen = Screen()

看上面的例子,main_screen就是首次加载draw模块式初始化的变量,不会重复初始化!

扩展module的加载路径

在加载module时,除了默认的寻找路径:主脚本目录以及内置module外,我们可以通过以下方法告知python解释器,哪里可以去寻找对应的module:

  • PYTHONPATH变量:
  • sys.path.append
  1. PYTHONPATH=/foo python game.py
  2. sys.path.append("/foo") #在执行import之前运行该代码

built-in modules

和每个python发行版伴随的有很多内置的Python库,这些built-in modules使用C语言编写,提供诸如访问系统功能比如文件I/O的功能,这些库也提供一些常见问题的通用解决方案供调用。还有部分builtin模块用于抽象Python应用程序,以便和平台无关。

https://docs.python.org/3/library/

比如,我们向使用urllib这个内置库:

  1. # import the library
  2. import urllib
  3.  
  4. # use it
  5. urllib.urlopen(...)

我们可以通过dir函数来列出一个module中定义的函数:

  1. >>> import urllib
  2. >>> dir(urllib)
  3. ['ContentTooShortError', 'FancyURLopener', 'MAXFTPCACHE', 'URLopener', '__all__', '__builtins__',
  4. '__doc__', '__file__', '__name__', '__package__', '__version__', '_ftperrors', '_get_proxies',
  5. '_get_proxy_settings', '_have_ssl', '_hexdig', '_hextochr', '_hostprog', '_is_unicode', '_localhost',
  6. '_noheaders', '_nportprog', '_passwdprog', '_portprog', '_queryprog', '_safe_map', '_safe_quoters',
  7. '_tagprog', '_thishost', '_typeprog', '_urlopener', '_userprog', '_valueprog', 'addbase', 'addclosehook',
  8. 'addinfo', 'addinfourl', 'always_safe', 'basejoin', 'c', 'ftpcache', 'ftperrors', 'ftpwrapper', 'getproxies',
  9. 'getproxies_environment', 'getproxies_macosx_sysconf', 'i', 'localhost', 'main', 'noheaders', 'os',
  10. 'pathname2url', 'proxy_bypass', 'proxy_bypass_environment', 'proxy_bypass_macosx_sysconf', 'quote',
  11. 'quote_plus', 'reporthook', 'socket', 'splitattr', 'splithost', 'splitnport', 'splitpasswd', 'splitport',
  12. 'splitquery', 'splittag', 'splittype', 'splituser', 'splitvalue', 'ssl', 'string', 'sys', 'test', 'test1',
  13. 'thishost', 'time', 'toBytes', 'unquote', 'unquote_plus', 'unwrap', 'url2pathname', 'urlcleanup', 'urlencode',
  14. 'urlopen', 'urlretrieve']

当我们发现了我们希望使用的module中的某个function,还可以通过help命令来列出对应的帮助信息.

  1. help(urllib.urlopen)

pypi第三方modules

虽然python本身内置了非常丰富的package供程序员使用,但是依然有很多场景需要加载第三方的package,比如numpy, pandas等等。。

https://pypi.org/

开发package

packages是包含了多个package和module的命名空间。简单来说,package就是一些目录,仅此而已。只要目录中包含了一个命名为__init__.py的特殊文件,我们就称该目录为一个package。这个文件本身可以是空的,这个文件的存在标识了该目录为一个python package.

比如,如果我们创建一个目录:foo,那么foo作为package名称,然后我们创建一个模块并命名为bar.py,我们不要忘记在foo目录下增加一个__init__.py的文件。那么要使用这个bar模块,我们可以这样做:

  1. import foo.bar
  2. # 或者:
  3. from foo import bar

在__init__.py文件中,我们可以指定哪些模块作为暴露的api,而其他的模块作为私有的:

  1. __init__.py:
  2.  
  3. __all__ = ["bar"]

python modules and packages的更多相关文章

  1. Python Modules and Packages – An Introduction

    This article explores Python modules and Python packages, two mechanisms that facilitate modular pro ...

  2. 解决yum升级的问题“There was a problem importing one of the Python modules”

    yum命令升级的时候,报出这个错误. There was a problem importing one of the Python modules required to run yum. The ...

  3. Python Modules

    [Python Modules] 1. a module is a python source file. 2. a package is a directory with a __init__.py ...

  4. Installing Python Modules

    Email: distutils-sig@python.org As a popular open source development project, Python has an active s ...

  5. [Python] Reuse Code in Multiple Projects with Python Modules

    A module is a function extracted to a file. This allows you to import the function and use it in any ...

  6. [Python Modules] unittest.mock

    五夜光寒,照来积雪平于栈.西风何限,自起披衣看. 对此茫茫,不觉成长叹.何时旦,晓星欲散,飞起平沙雁. 在某个Python程序中看到这么一行 from unittest import mock 看起来 ...

  7. centos系统重装python或yum 报There was a problem importing one of the Python modules required to run yum. The error leading to this problem was:错误

    sudo vim /usr/bin/yum #修个python所在的路径,例如 #/usr/local/bin/python2.6 或 /usr/local/bin/python2.7要原本你的系统原 ...

  8. [Dynamic Language] 用Sphinx自动生成python代码注释文档

    用Sphinx自动生成python代码注释文档 pip install -U sphinx 安装好了之后,对Python代码的文档,一般使用sphinx-apidoc来自动生成:查看帮助mac-abe ...

  9. 后台运行python程序 遇到缓冲区问题

    From: http://www.iteye.com/topic/867446 环境:linux 一段执行时间很长的程序(用python做hive客户端执行mapreduce) 在linux后台执行, ...

随机推荐

  1. puppet的使用:安装puppet

    最近项目要使用puppet,趁机赶紧学习下. 在家里的机器中搭建puppet环境,使用两台ubuntu 14.04: 准备工作 时间同步 两台设备先进行时间同步,我把要安装master的机器作为NTP ...

  2. (01)JVM-内存三大核心区域以及分析

    package org.burning.sport.jvm; /** *  从JVM调用的角度分析Java程序对内存空间的使用, * 当JVM进程启动的时候,会从类加载器路径中找到包含main方法的入 ...

  3. 拦截并记录数据库操作-Logging and Intercepting Database Operations

    原文:http://msdn.microsoft.com/zh-cn/data/dn469464 Logging and Intercepting Database Operations Starti ...

  4. 将之前的DotNetOpenAuth项目发布到IIS

    首先需要安装IIS: 控制面板\程序--打开或关闭Windows功能: 默认的不会全选的,需要手动展开选择,能选就全选上吧,特别是asp.net选项,不选的话发布的网站也运行不了. 安装完后需要注册a ...

  5. Android之ListView的使用技巧

    之前有总结过关于ListView的一些优化技巧,比如它的ConvertView的复用Recycler机制,使用ViewHolder来提高列表条目的findById的效率,以及宽高的设置确定值的好处,如 ...

  6. Python -- 网络编程 -- 认识Python3的urllib库

    Python3的urllib包含5个模块 urllib error parse request response robotparser 各个模块的主要成员: error ['ContentTooSh ...

  7. spring整合mongodb

    使用spring整合mongodb maven 依赖 <dependency> <groupId>org.mongodb</groupId> <artifac ...

  8. Memcached理解笔记1---安装&常规错误&监控

    一.下载 1.Libevent 简单的说就是一个事件触发的网络库,Memcached离不开它. wget http://cloud.github.com/downloads/libevent/libe ...

  9. 用java实现一个简易编译器1-词法解析入门

    本文对应代码下载地址为: http://download.csdn.net/detail/tyler_download/9435103 视频地址: http://v.youku.com/v_show/ ...

  10. [IMX6]Android6.0移植和分析

    0. 知识点 中断(设备树) [IMX6]设备树分析--dts 1. 编译 Android6.0内核移植(1):分析编译日志 Android6.0内核移植(2):kernel编译内核 单独烧录kern ...