简介

现在你已经知道通过定义函数可以在你的程序中复用代码。但当你想在你编写的其他程序中复用大量函数怎么办呢?

也许你可以猜到了,办法就是利用模块。

有各种编写模块的方式,但最简单的方式是创建一个以.py为后缀的文件并包含所需的函数与变量。

另一种方式是以编写python解释器的本地语言编写模块。

例如C语言编写的模块被编译后可供运行于标准python解释器上的python代码使用。

模块可以被其它程序导入以使用其提供的功能。这也是为什么我们可以使用python标准库。

我们先来看看如何使用标准库模块。

范例:

#!/usr/bin/python

# Filename: using_sys.py

import sys

print('The command line arguments are:')

for i in sys.argv:

print(i)

print('/n/nThe PYTHONPATH is', sys.path, '/n')

输出:

$ python using_sys.py we are arguments

The command line arguments are:

using_sys.py

we

are

arguments

The PYTHONPATH is ['', 'C://Windows//system32//python30.zip',

'C://Python30//DLLs', 'C://Python30//lib',

'C://Python30//lib//plat-win', 'C://Python30',

'C://Python30//lib//site-packages']

工作流程:

首先我们使用import语句导入sys模块。本质上这告诉python我们希望使用这个模块。

sys模块包含python解释器与其工作环境(即系统)相关的功能。

当python执行import sys语句时,它将查找sys模块。本例中sys是内建模块之一,因此python知道在哪能找到它。

如果导入的不是一个编译模块,即不是用python编写的模块,python解释器会在变量sys.path中列出的目录中查找它。

(注:if it was not a compiled module i.e. a module written in Python)

如果模块被找到,这个模块中的语句将被执行然后你就可以使用它了(注: 只有顶级语句才会执行,也就是主块中的语句)。

注意一个模块只有在第一次导入时会被初始化。

sys模块中的argv通过点号引用即sys.argv。它清晰的指出这个名字是sys模块中的一部分。

这种语法的另一个优势是不会和你的程序中的同名argv变量发生冲突。

变量sys.argv是一个字符串列表(后章会详细解释列表)。

具体说sys.argv是一个包含命令行参数的列表,也就是使用命令行传递给你的程序的参数。

如果你在使用IDE编写程序,请在菜单中查找为程序指定命令行参数的方法。

这里,当我们执行python using_sys.py we are arguments时,我们以python命令运行using_sys.py模块,其后的内容是传递给程序的参数。

python将它们存到sys.argv以供我们使用。

记住,被运行脚本的脚本名永远是sys.argv的第一个参数。

所以本例中sys.argv[0]’using_sys.py’sys.argv[1]’we’sys.argv[2]’are’, argv[3]’arguments’。注意python下标从0开始而非1

sys.path包含一个目录名列表指示从哪里导入模块。

观察程序输出,sys.path的第一个字符串为空 – 其指出当前目录也是sys.path的一部分,这与PYTHONPATH环境变量是相同的。

这意味着你可以直接导入当前目录下的模块,否则你就必须将你的模块放到sys.path列出的目录中的一个了。

注意程序在哪个目录运行的,这个目录就是这个程序的当前目录。运行import os; print(os.getcwd()) 可以看到你的程序的当前目录。

(注:windows下sys.path[0]可能不为空,而是显式指出当前路径)

字节编译文件 .pyc

导入模块是一个相对昂贵的操作,所以python使用了一些技巧加速这个过程。

一个办法是创建后缀为.pyc的字节编译文件用于将程序转换为中间格式。(还记得介绍python如何工作的那一节吗?)

当你下次从其他文件导入模块时pyc文件会非常有用 – 它将大大增加导入速度,因为导入模块的部分操作已经预先完成了。

并且这个字节编译文件仍然是平台无关的。

注意

.pyc文件一般被创建在与其对应的.py文件所在的相同目录下。如果python没有这个目录的写权限,则.pyc文件不会被创建。

from…import…语句

如果你希望将变量argv直接导入到你的程序中(避免每次输入sys.),那么可以使用from sys import argv语句。

如果希望导入sys模块中的所有名字,则from sys import *可以做到。此语句可以用于任何模块。

通常你应该避免使用这个语句并用import语句代替之,因为使用后者可以避免名字冲突,程序的可读性也更好。

模块的__name__属性

每个模块都有一个名字,并且通过模块中的某些语句可以得到这个模块名。

在一些想要搞清模块是独立运行还是被导入的情况下,这会非常方便。

如前所述当模块第一次被导入时模块中的代码会被执行。我们可以据此改变模块独立执行时的行为方式。

这可以通过模块的__name__属性做到。(注:独立运行是指程序最开始运行的那个脚本文件(/模块))

范例:

#!/usr/bin/python

# Filename: using_name.py

if __name__ == '__main__':

print('This program is being run by itself')

else:

print('I am being imported from another module')

输出:

$ python using_name.py

This program is being run by itself

$ python

>>> import using_name

I am being imported from another module

>>>

工作流程:

每个python模块都有自己的__name__定义,如果它是’__main__’则暗示模块为独立运行,我们可以进行一些适当的处理。

制作你自己的模块

创建你自己的模块很简单,其实你一直在这样做!因为每个python脚本都是一个模块。你只需确保它带有.py扩展名即可。

下面的例子会让你对其有一个清晰的认识:

范例:

#!/usr/bin/python

# Filename: mymodule.py

def sayhi():

print('Hi, this is mymodule speaking.')

__version__ = '0.1'

# 结束mymodule.py编写

上面就是一个简单的模块,如你所见,这和我们平时的python程序相比没有什么特别之处。

记住模块应该放到导入它的那个程序所在的目录下,或者放到sys.path列出的目录之一中。

#!/usr/bin/python

# Filename: mymodule_demo.py

import mymodule

mymodule.sayhi()

print ('Version', mymodule.__version__)

输出:

$ python mymodule_demo.py

Hi, this is mymodule speaking.

Version 0.1

如何工作:

注意我们同样使用点号访问模块成员。

python很好的重复利用了相同的符号,带来独特的’Pythonic’感受,这样我们就不必学习更多的语法知识了。

下面是一个使用from…import语法的版本:

#!/usr/bin/python

# Filename: mymodule_demo2.py

from mymodule import sayhi, __version__

sayhi()

print('Version', __version__)Python en:Modules 59

mymodule_demo2.pymymodule_demo的输出完全相同。

注意,如果导入mymodule的模块中已经存在同名的__version__,则将发生名字冲突。

事实上这很可能发生,因为每个模块都用__version__声明它的版本是一种常见的做法。

因此建议你优先考虑import语句,虽然它可能会让你的程序变的更长一些。

你同样可以使用:

from mymodule import *

这将导入模块的所有公有名字,例如sayhi,但是不会导入__version__因为它以双下划线开头。

Python之禅

python的一个指导原则是”清晰的好过隐晦的”. 执行import this可以看到完整内容。

这里的讨论列出了每个原则的范例(http://stackoverflow.com/questions/228181/zen-of-python)

dir函数

你可以使用dir函数列出一个对象定义的所有标识符。例如对于一个模块,标识符包括函数,类,变量。

当你为dir()函数提供一个模块名,它将返回定义在其中的所有名字。

dir()的参数为空时,返回定义在当前模块中所有名字。

范例:

$ python

>>> import sys # 得到sys模块的属性列表

>>> dir(sys)

['__displayhook__', '__doc__', '__excepthook__', '__name__',

'__package__', '__stderr__', '__stdin__', '__stdout__', '_clear_type_cache',

'_compact_freelists', '_current_frames', '_getframe', 'api_version', 'argv',

'builtin_module_names', 'byteorder', 'call_tracing', 'callstats', 'copyright', 'displayhook',

'dllhandle', 'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix', executable',

'exit', 'flags', 'float_info', 'getcheckinterval', 'getdefaultencoding', 'getfil

esystemencoding', 'getprofile', 'getrecursionlimit', 'getrefcount', 'getsizeof',

'gettrace', 'getwindowsversion', 'hexversion', 'intern', 'maxsize', 'maxunicode',

'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform',

'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setprofile', 'setrecursionlimit',

'settrace', 'stderr', 'stdin', 'stdout', 'subversion', 'version', 'version_info', 'warnoptions', 'winver']

>>> dir() # 得到当前模块的属性列表

['__builtins__', '__doc__', '__name__', '__package__', 'sys']

>>> a = 5 # create a new variable 'a'

>>> dir()

['__builtins__', '__doc__', '__name__', '__package__', 'a', 'sys']

>>> del a # 删除名字a

>>> dir()

['__builtins__', '__doc__', '__name__', '__package__', 'sys']

工作流程:

首先,我们通过被导入的sys模块应用dir函数. 可以看到sys包含巨多的属性。

接下来,我们不为dir函数提供参数。默认的它返回当前模块的属性列表。注意被导入模块列表也是当前模块列表的一部分。

为了观察到dir确定起作用了,我们定义一个新变量a并为其赋值然后检验dir的返回值,我们发现在返回的列表中确实出现

了一个与变量a同名的值。在我们使用del语句删除当前模块的变量/属性后,改变再次反映到了dir函数的输出上。

del注解 – 这个语句用于删除一个变量/名字,在本例中,del a之后你就无法访问变量a了 – 就像它从来没有存在过一样。

注意dir()函数可用于任何对象。例如执行dir (print)学习更多关于print函数的属性,或是dir(str)列出str类的属性。

如今,你必须开始留心组织你的程序层次了。

变量在函数内部,函数和全局变量通常在模块内部。那么如何组织模块呢?这就轮到登场了。

仅仅是包含模块的文件夹,并带有一个特殊的文件__init__.py用于指示python这个文件夹是特殊的,因为它包含python模块。

让我们假设你需要创建一个叫做’world’的包,里面包括诸如’asia’‘africa’等的子包。

下面告诉你应该如何组织文件夹结构:

- <some folder present in the sys.path>/

- world/

- __init__.py

- asia/

- __init__.py

- india/

- __init__.py

- foo.py

- africa/

- __init__.py

- madagascar/

- __init__.py

- bar.py

包只是用来有层次的组织模块。你会在标准库中看到它的很多应用。

小结

就象函数是程序的可复用部分一样,模块是可复用的程序。

包用于组织模块的层次结构。python自带的标准库正是一组包和模块的范例。

我们已经看到如何使用这些模块,并且知道如何创建自己的模块。

接下来,我们将学习一个比较有趣的概念 – 数据结构。

简明Python3教程 10.模块的更多相关文章

  1. 简明Python3教程(A Byte of Python 3)

    关键字:[A Byte of Python v1.92(for Python 3.0)] [A Byte of Python3] 简明Python教程 Python教程 简明Python3教程  简明 ...

  2. 简明Python3教程 9.函数

    简介 函数是程序的可复用片段,允许你为语句块赋予名字之后在程序的任何地方运行它们任意次,这称做函数调用. 我们已经使用过一些内建函数,例如len和range等. 函数也许是任何有意义的软件中最重要的构 ...

  3. 简明Python3教程 18.下一步是什么

    如果你有认真通读本书之前的内容并且实践其中包含的大量例程,那么你现在一定可以熟练使用python了. 同时你可能也编写了一些程序用于验证python特性并提高你的python技能.如果还没有这样做的话 ...

  4. 简明Python3教程 16.标准库

    简介 python标准库作为python标准安装的一部分,其自身包含数量庞大的实用模块, 因此熟悉python标准库非常重要,因为很多问题都能利用python标准库快速解决. 下面我们将研究标准库中的 ...

  5. 简明Python3教程 12.问题解决

    我们已经探究了python语言的方方面面,现在我们将通过设计编写一个有用的程序将这些内容有机的结合起来. 主要目标是让大家有能力独自编写程序. 问题 我们要解决的问题是”希望编写一个程序,用于创建所有 ...

  6. 简明Python3教程 6.基础

    你肯定不满足于只打印"Hello World"吧? 你想要的更多 - 你希望得到一些输入,操纵它后再从中得到某些东西.我们可以使用python中的常量和变量实现这些功能. 字面常量 ...

  7. 简明Python3教程 5.第一步

    介绍 我们现在来看看如何在Python中运行传统的”Hello world”程序.这会教你如何写.保存以及运行Python程序. 有两种办法来运行您的Python程序——使用交互式的解释器提示符或者源 ...

  8. 简明python教程四-----模块

    模块基本是一个包含了所有你定义的函数和变量的文件.为了在其他程序中重用模块,模块的文件名必须以.py为扩展名. #!/usr/bin/python #Filename:using_sys.py imp ...

  9. 简明Python3教程 1.介绍

    Python是少有的几种既强大又简单的编程语言.你将惊喜地发现通过使用Python即可轻松专注于解决问题而非和你所用的语言格式与结构. 下面是Python的官方介绍: Python is an eas ...

随机推荐

  1. Win7长时间使用占用内存高问题记

    工作电脑Win7 64位,8G内存,没设置虚拟内存,连续运行几天,中间只是睡眠,今天在试用时总提示内存不足,看任务管理器已经把占用内存比较多的几个进程都结束掉了,但内存占用依旧是80%以上,eclip ...

  2. 搭建MHA问题汇总

    1,Can't exec "mysqlbinlog": No such file or directory at /usr/share/perl5/vendor_perl/MHA/ ...

  3. mha && 脚本拉起

    ip分布:  vip 192.168.238.222 mha_manager 192.168.238.131 监控服务器 master 192.168.238.128 主库GTID复制模式 slave ...

  4. JVM调优2

    原文地址:https://blog.csdn.net/sun1021873926/article/details/78002118 一.什么是JVM  JVM是Java Virtual Machine ...

  5. 使用LAMP创建基于wordpress的个从博客网站 分类: B3_LINUX 2014-07-15 16:45 800人阅读 评论(0) 收藏

    参考: http://blog.csdn.net/ck_boss/article/details/27866117 一.mysql配置 1.安装mysql yum install mysql-serv ...

  6. wdcp忘记mysql的root密码

    复制别人的 不管出于何种原因,应该有不少的朋友在自己的VPS/服务器上采用WDCP管理面板的时候有忘记MYSQL ROOT账户管理密码在寻找解决方法,甚至有忘记WDCP后台管理登录密码的.这些问题都比 ...

  7. 第一次使用docker for windows 遇到的坑

    原文:第一次使用docker for windows 遇到的坑 1. 目前win10安装docker, 不需要安装其他工具,可直接到官网下载 2. 此版本的docker可同时运行Windows con ...

  8. 【U218】A-B

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 给出一个A/B-C/D表示的分数减法算式,A,B,C,D均为不超过32767的正整数,求A/B-C/D ...

  9. arcengine 要素类的复制

    转自原文arcengine 要素类的复制 using System; using System.Collections.Generic; using System.Text; using ESRI.A ...

  10. .gitignore 设置忽略上传的文件

    首先在一个项目中新建如下所示文件用来测试 image.png 一.生成.gitignore文件 1.进入项目根目录,打开终端: 2.输入 vi .gitignore 创建并打开隐藏文件.gitigno ...