充电时刻——模块

python的标准安装包含一组模块,称为标准库。

模块

>>> import math

>>> math.sin(0)

0.0

模块是程序

不论什么python程序都能够作为模块导入。

$ cat hello.py

#!/usr/bin/python

print "Hello,signjing!"

$ ./hello.py

Hello,signjing!

如果将python程序保存在/home/ggz2/magiccube/mysh/pys文件夹中,运行以下的代码:

>>> import sys

>>> sys.path.append('/home/ggz2/magiccube/mysh/pys')

这里所做的仅仅是告诉解释器:除了从默认的文件夹中寻找之外,还须要从文件夹/home/ggz2/magiccube/mysh/pys中寻找模块。

完毕这个步骤后,就能导入自己的模块了:

>>> import hello

Hello,signjing!

注意:在导入模块的时候。可能会看到有新文件出现,本例中是/home/ggz2/magiccube/mysh/pys/hello.pyc。这个以.pyc为扩展名的文件是(平台无关的)经过处理(编译)的,已经转换成python可以更加有效地处理的文件。假设稍后导入同一个模块,python会导入.pyc文件而不是.py文件。除非.py文件已经改变——在这样的情况下,会生成新的.pyc文件。

删除.pyc文件不会损害程序(仅仅要等效的.py文件存在就可以)——必要的时候会创建新的.pyc文件。

如你所见。在导入模块的时候。当中的代码就被运行了。只是再次导入该模块。就不会发生什么了。

>>> import hello

>>>

由于导入模块并不意味着在导入时运行某些操作。

它们主要用于定义。

此外,由于仅仅须要定义这些东西一次,导入模块多次和导入一次的效果是一样的。

模块用于定义

模块在第一次导入程序中时被运行。

这看起来有点用——但并不算非常实用。真正的用处在于它们(像类一样)能够保持自己的作用域。这就意味着定义的全部类和函数以及赋值后的变量都成为了模块的特性。

在模块中定义函数

$ cat hello2.py

#!/usr/bin/python

def hello():

print "morning,signjing"

>>> import hello2

>>> hello2.hello()

morning,signjing

能够通过相同的方法来使用不论什么在模块的全局作用域中定义的名称。

为了让代码可重用,请将它模块化!

在模块中添加測试代码

模块用来定义函数、类和其它一些内容。但有些时候(其实是常常)。在模块中加入一些检查模块本身是否正常工作的測试代码是非常实用的。

$ cat  hello3.py

#!/usr/bin/python

def hello():

print "Hello!"

# a test

hello()

>>> import hello3

Hello!

>>> hello3.hello()

Hello!

避免这样的情况的关键在于:“告知”模块本身是作为程序执行还是导入到其它程序。为了实现这一点。须要使用__name__(双下划线)变量:

>>> __name__

'__main__'

>>> hello3.__name__

'hello3'

可见。在主程序(包含解释器的交互式提示符在内)中。变量__name__的值是’__main__’。而在导入的模块中。这个值被设定为模块的名字。因此。为了让模块的測试代码更加好用,能够将其放置在if语句中:

$ cat hello4.py

#!/usr/bin/python

def hello():

print "hello"

def test():

hello()

if __name__=='__main__':test()

>>> import hello4

>>>

>>> hello4.hello()

hello

让你的模块可用

将模块放置在正确位置

将你的模块放置在正确位置(或者某个正确位置)是非常easy的。仅仅须要找出python解释器从哪里查找模块。然后将自己的文件放置在那里就可以。

linux系统:

>>> import sys,pprint

>>> pprint.pprint(sys.path)

['',

'/usr/lib64/python26.zip',

'/usr/lib64/python2.6',

'/usr/lib64/python2.6/plat-linux2',

'/usr/lib64/python2.6/lib-tk',

'/usr/lib64/python2.6/lib-old',

'/usr/lib64/python2.6/lib-dynload',

'/usr/lib64/python2.6/site-packages',

'/usr/lib64/python2.6/site-packages/gtk-2.0',

'/usr/lib/python2.6/site-packages']

windows系统:

>>> import sys,pprint

>>> pprint.pprint(sys.path)

['',

'D:\\software(x86)\\Python27\\Lib\\idlelib',

'C:\\Windows\\system32\\python27.zip',

'D:\\software(x86)\\Python27\\DLLs',

'D:\\software(x86)\\Python27\\lib',

'D:\\software(x86)\\Python27\\lib\\plat-win',

'D:\\software(x86)\\Python27\\lib\\lib-tk',

'D:\\software(x86)\\Python27',

'D:\\software(x86)\\Python27\\lib\\site-packages']

每一个字符串都提供了一个放置模块的文件夹。解释器能够从这些文件夹中找到所需的模块。虽然这些文件夹都能够使用。但site-packages文件夹是最佳选择,由于它就是用来做这些事情的。

在windows操作系统中的D:\\software(x86)\\Python27\\lib\\site-packages下创建文件another_hello.py:

def hello():

print "hello,Win7"

>>> import another_hello

>>> another_hello.hello()

hello,Win7

可见。仅仅要将模块放入类似site-packages这种文件夹中,全部程序就都能将其导入了。

告诉编译器去哪里找

“将模块放置在正确的位置”这个解决方式在下面几种情况下可能并不适用:

1)不希望将自己的模块填满python解释器的文件夹;

2)没有python解释器文件夹中存储文件的权限。

3)想将模块放在其它地方

既然如此,那就告诉解释器去哪里找。之前提到了sys.path。但这不是通用的方法。标准的实现方法是在PYTHONPATH环境变量中包括模块所在的文件夹。

PYTHONPATH环境变量的内容会由于使用的操作系统不同而有所差异,但从基本上来说。它与sys.path非常类似——一个文件夹列表。

环境变量并非python解释器的一部分。它们是操作系统的一部分。

提示:不须要使用PYTHONPATH来更改sys.path。

路径配置文件提供了一个实用的捷径。能够让python替你完毕这些工作。路径配置文件是以.pth为扩展名的文件,包含应该加入到sys.path中的文件夹信息。空行和以#开头的行都会被忽略。

以import开头的文件会被运行。对于Windows来说,使用sys.prefix定义的文件夹名;在unix和mac OSX中则使用site-packages文件夹。

命名模块

包括模块代码的文件要和模块名一样——再加上.py扩展名。

在windows系统中,也能够使用.pyw扩展名。

为了组织好模块,能够将它们分组为包。包基本上就是另外一类模块。

有趣的地方就是它们都能包括其它模块。

当模块存储在文件里时(扩展名为.py),包就是模块所在的文件夹。为了让python将其作为包对待。它必须包括一个命名为__init__py的文件(模块)。假设将它作为普通模块导入的话,文件的内容就是包的内容。比方有个名为constants的包,文件constants/__init__.py包括语句PI=3.14,那么能够这么做:

import constants

print constants.PI

为了将模块放置在包内。直接把模块放在包文件夹内就可以。

探究模块

怎样独立地探究模块,是极有价值的技能。由于职业生涯中可能会遇到非常多实用的模块。

模块中有什么

探究模块最直接的方式就是在python解释器中研究它们。

第一件事就是导入它。

如果有个叫做copy的标准模块:

>>> import copy

使用dir

查看模块中包括的内容能够使用dir函数,会将对象(以及模块的全部函数、类、变量等)的全部特性列出。

>>> dir(copy)

['Error', 'PyStringMap', '_EmptyClass', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_copy_dispatch', '_copy_immutable', '_copy_inst', '_copy_with_constructor', '_copy_with_copy_method', '_deepcopy_atomic', '_deepcopy_dict', '_deepcopy_dispatch', '_deepcopy_inst', '_deepcopy_list', '_deepcopy_method', '_deepcopy_tuple', '_keep_alive', '_reconstruct', '_test', 'copy', 'deepcopy', 'dispatch_table', 'error', 'name', 't', 'weakref']

一些名字下面划线開始——暗示(约定俗成)它们并非为在模块外部使用而准备的。过滤到它们:

>>> [n for n in dir(copy) if not n.startswith('_')]

['Error', 'PyStringMap', 'copy', 'deepcopy', 'dispatch_table', 'error', 'name', 't', 'weakref']

all变量

__all__这个名字包括一个列表,在copy模块内部被设置。

>>> copy.__all__

['Error', 'copy', 'deepcopy']

它定义了模块的公共接口。

更准确地说,它告诉解释器:从模块导入全部名字代表什么含义。

使用例如以下代码from copy import *。则仅仅能使用__all__变量中的函数。要导入PyStringMap的话,就得显式地实现,或者导入copy然后使用copy.PyStringMap,或者使用from copy import PyStringMap。

在编写模块的时候,像设置__all__这种技术还是相当实用的。

由于模块中可能会有一大堆其它程序不须要或不想要的变量、函数和类,__all__会“客气地”将它们过滤了出去。

假设没有设定__all__,用import *语句默认将会输出模块中全部不下面划线开头的全局名称。

用help获取帮助

对于探究工作。交互式解释器是个很强大的工具。而对该语言的精通程度决定了对模块探究的程度。只是还有个标准函数可以为你提供日常所需的信息,这个函数叫做help。

>>> help(copy.copy)

Help on function copy in module copy:

copy(x)

Shallow copy operation on arbitrary Python objects.

See the module's __doc__ string for more info.

>>>

其实。上面的帮助文档是从copy函数的文档字符串中提取出的:

>>> print copy.copy.__doc__

Shallow copy operation on arbitrary Python objects.

See the module's __doc__ string for more info.

>>>

使用help与直接检查文档字符串相比。优点在于获得很多其它信息。

help(copy)会打印出很多其它信息,此处略;

文档

并不是每一个模块或函数都有不错的文档字符串(虽然都应该有)。有些时候可能须要十分透彻地描写叙述这些模块和函数是怎样工作的。

学习python编程最实用的文档莫过于python库參考。它对全部标准库中的模块都有描写叙述。

使用源码

对于希望真正理解python语言的人来说。要了解模块,是不能脱离源码的。

阅读源码其实是学习python最好的方式——除了自己编写代码外。

真正的阅读不是问题,可是问题在于源码那里。假设希望阅读标准模块copy的源码。一种方案是检查sys.path。然后自己找。还有一种是检查模块的__file__属性:

>>> copy.__file__

'D:\\software(x86)\\Python27\\lib\\copy.pyc'

注意:一些模块并不包括不论什么能够阅读的python源码。它们可能已经融入到解释器内了(比方sys模块),或者可能是使用c语言写成的。

python基础教程_学习笔记12:充电时刻——模块的更多相关文章

  1. python基础教程_学习笔记14:标准库:一些最爱——re

    标准库:一些最爱 re re模块包括对正則表達式的支持,由于以前系统学习过正則表達式,所以基础内容略过,直接看python对于正則表達式的支持. 正則表達式的学习,见<Mastering Reg ...

  2. python基础教程_学习笔记19:标准库:一些最爱——集合、堆和双端队列

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/signjing/article/details/36201499 标准库:一些最爱 集合.堆和双端队 ...

  3. python基础教程_学习笔记1:序列-1

    序列 数据结构:通过某种方式组织在一起的数据元素的集合,这些数据元素能够是数字或者字符,甚至能够是其它数据结构. python中,最主要的数据结构是序列. 序列中的每一个元素被分配一个序号--即元素的 ...

  4. python基础教程_学习笔记10:异常

    异常 什么是异常 Python用异常对象来表示异常情况.遇到错误后,会引发异常.假设异常对象并未被处理或捕捉,程序就会用所谓的回溯(Traceback,一种错误信息)终止运行: >>> ...

  5. python基础教程_学习笔记9:抽象

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/signjing/article/details/30745465 抽象 懒惰即美德. 抽象和结构 抽 ...

  6. python基础教程_学习笔记11:魔法方法、属性和迭代器

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/signjing/article/details/31417309 魔法方法.属性和迭代器 在pyth ...

  7. python基础教程_学习笔记18:标准库:一些最爱——shelve

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/signjing/article/details/36029981 标准库:一些最爱 shelve S ...

  8. python基础课程_学习笔记15:标准库:有些收藏夹——fileinput

    标准库:有些收藏夹 fileinput 重要功能 性能 叙述性说明 input([files[,inplace[,backup]]) 便于遍历多个输入流中的行 filename() 返回当前文件的名称 ...

  9. python基础课程_学习笔记26:编程的乐趣

    编程的乐趣 编程柔术 当你坐下来,打算如何组织计划要定时,具体程序,然而,无论什么经验.在实现时间的函数的,你会逐渐学会了原来的设计,实用的新知识.我们不应该忽视沿途汲取的教训,相反,它们用于其他设计 ...

随机推荐

  1. qwb与学姐 (带秩并查集)

    qwb与学姐 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 149  Solved: 54[Submit][Status][Web Board] Des ...

  2. CDH-hive支持insert、update、delete操作

    开发要求hive支持update操作,搞张临时表测试下,报错如下: 配置hive-site.xml CDH进入hive配置页,选择高级,找到hive-site.xml的HIve客户端高级配置段代码段, ...

  3. application.xml

    application.xml Deployment Descriptor Elements The following sections describe the application.xml f ...

  4. 在spring中手动编写事务

    利用事务模板TransactionTemplate来手动添加事务 public void addRant(Rant rant) { transactionTemplate.execute(-?tran ...

  5. VB查询数据库之报表——机房收费系统总结(六)

    我们要用一个软件做报表的模板.然后在VB里面添加部件.代码调用模板,详细步骤如下. 一.下载安装 首先做报表要下载安装Grid++Report 4.5 报表设计器 点击下载(内含破解补丁) 二.制作模 ...

  6. CSS 笔记——文本字体

    5. 文本字体 -> 文本 (1)text-indent 基本语法 text-indent : length 语法取值 length : 百分比数字 | 由浮点数字和单位标识符组成的长度值,允许 ...

  7. [P4063][JXOI2017]数列(DP)

    题目描述 九条可怜手上有一个长度为 n 的整数数列 ri,她现在想要构造一个长度为 n 的,满足如下条件的整数数列 A: • 1 ≤ Ai ≤ ri. • 对于任意 3 ≤ i ≤ n,令 R 为 A ...

  8. [bzoj1010](HNOI2008)玩具装箱toy(动态规划+斜率优化+单调队列)

    Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有 的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1.. ...

  9. Font Include Sass Mixin

    前端开发whqet,csdn,王海庆,whqet,前端开发专家 前期以前给大家介绍过一个使用google font的mixin(详见<Google Fonts Sass Mixin>),今 ...

  10. andriod获得textView的值设置textView的text

    TextView pTextView=(TextView)findViewById(R.id.textView2);String str=pTextView.getText().toString(); ...