9.1 自定义模块
自定义模块你已经会了,平常写的代码放到一个文件里面就是啦!
例如,写个简单的函数,作为一个模块:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<code>#!/usr/bin/python</code>
<code># -*- coding: utf-8 -*-</code>
<code>def</code> <code>func(a, b):</code>
<code> </code><code>return</code> <code>a </code><code>*</code> <code>b</code>
<code>class</code> <code>MyClass:</code>
<code> </code><code>def</code> <code>__init__(</code><code>self</code><code>, a, b):</code>
<code> </code><code>self</code><code>.a </code><code>=</code> <code>a</code>
<code> </code><code>self</code><code>.b </code><code>=</code> <code>b</code>
<code> </code><code>def</code> <code>method(</code><code>self</code><code>):</code>
<code> </code><code>return</code> <code>self</code><code>.a </code><code>*</code> <code>self</code><code>.b</code>
<code>导入模块:</code>
<code>>>> </code><code>import</code> <code>test</code>
<code>>>> test.func(</code><code>2</code><code>, </code><code>2</code><code>)</code>
<code>4</code>
<code>>>> c </code><code>=</code> <code>test.MyClass(</code><code>2</code><code>, </code><code>2</code><code>)</code>
<code>>>> c.method()</code>
是不是很简单!是的,没错,就是这样。
需要注意的是,test就是文件名。另外,模块名要能找到,我的是在当前目录下。
有时经常from...import...,这又是啥呢,来看看:
<code>>>> </code><code>from</code> <code>test </code><code>import</code> <code>func, MyClass </code><code># 多个函数或类以逗号分隔</code>
<code>Traceback (most recent call last):</code>
<code> </code><code>File</code> <code>"<stdin>"</code><code>, line </code><code>1</code><code>, </code><code>in</code> <code><module></code>
<code>NameError: name </code><code>'test'</code> <code>is</code> <code>not</code> <code>defined</code>
<code>>>> func(</code><code>2</code><code>, </code><code>2</code><code>)</code>
<code>>>> c </code><code>=</code> <code>MyClass(</code><code>2</code><code>, </code><code>2</code><code>)</code>
看到了吧!如果你不想把模块里的函数都导入,就可以这样。一方面避免导入过多用不到的函数增加负载,另一方面引用时可不加模块名。
如果想调用不加模块名,也想导入所有模块,可以这样:
<code>>>> </code><code>from</code> <code>test </code><code>import</code> <code>*</code>
使用个星号就代表了所有。
提醒:在模块之间引用也是同样的方式。
博客地址:http://lizhenliang.blog.51cto.com
QQ群:323779636(Shell/Python运维开发群)
9.2 作为脚本来运行程序
所有的模块都有一个内置属性__name__,如果import一个模块,那么模块的__name__属性返回值一般是文件名。如果直接运行Python程序,__name__的值将是一个"__mian__"。
举例说明,根据上面程序做一个测试:
<code>print</code> <code>__name__</code>
<code># python test.py</code>
<code>__main__</code>
与预期一样,打印出了“__main__”,再创建一个test2.py,导入这个模块:
<code>import</code> <code>test</code>
<code># python test2.py</code>
<code>test</code>
打印出了模块名,这个结果输出就是test.py中的print __name__。
所以,我们在test.py里面判断下__name__值等于__main__时说明在手动执行这个程序:
<code>if</code> <code>__name__ </code><code>=</code><code>=</code> <code>"__main__"</code><code>:</code>
<code> </code><code>print</code> <code>"我在手动执行这个程序..."</code>
<code> </code>
<code>我在手动执行这个程序...</code>
此时再运行test2.py试试,是不是打印为空!明白了吧!
9.3 安装第三方模块
在Python中安装外部的模块有几种方式:
1)下载压缩包,通过setuptools工具安装,这个在第一章Python基础知识里面用到过。推荐下载地址:http://pypi.python.org
2)easy_install工具安装,也依赖setuptools。
3)pip工具安装。推荐使用这个方式。
4)直接将压缩包解压到Python模块目录。但常常会出现import失败,不推荐。
5)在Windows下,除了上面几种方式以外,可以直接下载exe文件点击一步步安装。
pip与easy_install安装方式类似,主要区别在于easy_install不支持卸载软件,而pip支持。
推荐使用pip命令安装,简单方便。如果安装失败可以按顺序这么尝试:方式1 --> 方式2 --> 方式4
以安装setuptools举例上面几种安装方式:
<code>方式</code><code>1</code><code>:</code>
<code># wget https://pypi.python.org/packages/32/3c/e853a68b703f347f5ed86585c2dd2828a83252e1216c1201fa6f81270578/setuptools-26.1.1.tar.gz</code>
<code># tar zxvf setuptools-26.1.1.tar.gz</code>
<code># cd setuptools-26.1.1</code>
<code># python setup.py install</code>
<code>方式</code><code>2</code><code>:</code>
<code># easy_install setuptools</code>
<code>方式</code><code>3</code><code>:</code>
<code># pip install setuptools</code>
<code># pip uninstall setuptools # 卸载</code>
<code># pip search setuptools # 搜索</code>
<code>cp </code><code>-</code><code>rf setuptools</code><code>-</code><code>26.1</code><code>.</code><code>1</code> <code>/</code><code>usr</code><code>/</code><code>local</code><code>/</code><code>lib</code><code>/</code><code>python2.</code><code>7</code><code>/</code><code>dist</code><code>-</code><code>packages</code>
9.4 查看模块帮助文档
前面几个章节已经使用几个内置模块了,比如collections、itertools等,导入与上面一样,这里不再过多说明了。
1)help()函数
当一个模块对其语法不了解时,可以查看帮助,以collections举例:
18
<code>>>> </code><code>import</code> <code>collections </code>
<code>>>> </code><code>help</code><code>(collections)</code>
<code>Help</code> <code>on module collections:</code>
<code>NAME</code>
<code> </code><code>collections</code>
<code>FILE</code>
<code> </code><code>/</code><code>usr</code><code>/</code><code>lib</code><code>/</code><code>python2.</code><code>7</code><code>/</code><code>collections.py</code>
<code>MODULE DOCS</code>
<code> </code><code>http:</code><code>/</code><code>/</code><code>docs.python.org</code><code>/</code><code>library</code><code>/</code><code>collections </code><code># 注意:这里是这个模块的帮助文档,很详细的哦!</code>
<code>CLASSES</code>
<code> </code><code>__builtin__.</code><code>dict</code><code>(__builtin__.</code><code>object</code><code>)</code>
<code> </code><code>Counter</code>
<code> </code><code>OrderedDict</code>
<code> </code><code>defaultdict</code>
<code> </code><code>__builtin__.</code><code>object</code>
<code> </code><code>_abcoll.</code><code>Callable</code>
<code> </code><code>_abcoll.Container</code>
<code> </code><code>......</code>
使用help()就能查看这个模块的内部构造,包括类方法、属性等信息。
也可以再对某个方法查看其用法:
19
20
<code>>>> </code><code>help</code><code>(collections.Counter()) </code>
<code>Help</code> <code>on Counter </code><code>in</code> <code>module collections </code><code>object</code><code>:</code>
<code>class</code> <code>Counter(__builtin__.</code><code>dict</code><code>)</code>
<code> </code><code>| </code><code>Dict</code> <code>subclass </code><code>for</code> <code>counting hashable items. Sometimes called a bag</code>
<code> </code><code>| </code><code>or</code> <code>multiset. Elements are stored as dictionary keys </code><code>and</code> <code>their counts</code>
<code> </code><code>| are stored as dictionary values.</code>
<code> </code><code>| </code>
<code> </code><code>| >>> c </code><code>=</code> <code>Counter(</code><code>'abcdeabcdabcaba'</code><code>) </code><code># count elements from a string</code>
<code> </code><code>| >>> c.most_common(</code><code>3</code><code>) </code><code># three most common elements</code>
<code> </code><code>| [(</code><code>'a'</code><code>, </code><code>5</code><code>), (</code><code>'b'</code><code>, </code><code>4</code><code>), (</code><code>'c'</code><code>, </code><code>3</code><code>)]</code>
<code> </code><code>| >>> </code><code>sorted</code><code>(c) </code><code># list all unique elements</code>
<code> </code><code>| [</code><code>'a'</code><code>, </code><code>'b'</code><code>, </code><code>'c'</code><code>, </code><code>'d'</code><code>, </code><code>'e'</code><code>]</code>
<code> </code><code>| >>> ''.join(</code><code>sorted</code><code>(c.elements())) </code><code># list elements with repetitions</code>
<code> </code><code>| </code><code>'aaaaabbbbcccdde'</code>
<code> </code><code>| >>> </code><code>sum</code><code>(c.values()) </code><code># total of all counts</code>
<code> </code><code>| </code><code>15</code>
<code> </code><code>| >>> c[</code><code>'a'</code><code>] </code><code># count of letter 'a'</code>
<code>......</code>
一般里面都是举例说明,可快速帮助我们回忆使用方法。
2)dir()函数查看对象属性
这个在前面也用到过,能看到对象的方法、属性等信息:
<code> </code><code>>>> </code><code>dir</code><code>(collections) </code>
<code> </code><code>[</code><code>'Callable'</code><code>, </code><code>'Container'</code><code>, </code><code>'Counter'</code><code>, </code><code>'Hashable'</code><code>, </code><code>'ItemsView'</code><code>, </code><code>'Iterable'</code><code>, </code><code>'Iterator'</code><code>, </code><code>'KeysView'</code><code>, </code><code>'Mapping'</code><code>, </code><code>'MappingView'</code><code>, </code><code>'MutableMapping'</code><code>, </code><code>'MutableSequence'</code><code>, </code><code>'MutableSet'</code><code>, </code><code>'OrderedDict'</code><code>, </code><code>'Sequence'</code><code>, </code><code>'Set'</code><code>, </code><code>'Sized'</code><code>, </code><code>'ValuesView'</code><code>, </code><code>'__all__'</code><code>, </code><code>'__builtins__'</code><code>, </code><code>'__doc__'</code><code>, </code><code>'__file__'</code><code>, </code><code>'__name__'</code><code>, </code><code>'__package__'</code><code>, </code><code>'_abcoll'</code><code>, </code><code>'_chain'</code><code>, </code><code>'_class_template'</code><code>, </code><code>'_eq'</code><code>, </code><code>'_field_template'</code><code>, </code><code>'_get_ident'</code><code>, </code><code>'_heapq'</code><code>, </code><code>'_imap'</code><code>, </code><code>'_iskeyword'</code><code>, </code><code>'_itemgetter'</code><code>, </code><code>'_repeat'</code><code>, </code><code>'_repr_template'</code><code>, </code><code>'_starmap'</code><code>, </code><code>'_sys'</code><code>, </code><code>'defaultdict'</code><code>, </code><code>'deque'</code><code>, </code><code>'namedtuple'</code><code>]</code>
3)github上查看模块用法
Python官方模块下载地址http://pypi.python.org,所有的模块在这里都有。
打开网站后,在搜索框搜索你的模块名,在结果找到模块名点进去,会有一个 Home Page的连接,Python大多数模块都是托管在github上面,这个链接就是这个模块在github上面的地址,点击后跳转到github对应的模块页面,里面也有很详细模块使用方法。
9.5 导入模块新手容易出现的问题
还有一个新手经常犯的问题,写一个模块,比如使用itertools模块,为了说明这个测试文件是这个模块,就把文件名写成了这个模块名,于是就造成了下面错误:
<code>import</code> <code>collections</code>
<code>c </code><code>=</code> <code>collections.Counter()</code>
<code>for</code> <code>i </code><code>in</code> <code>"Hello world!"</code><code>:</code>
<code> </code><code>c[i] </code><code>+</code><code>=</code> <code>1</code>
<code>print</code> <code>c</code>
<code># python collections.py</code>
<code> </code><code>File</code> <code>"collections.py"</code><code>, line </code><code>3</code><code>, </code><code>in</code> <code><module></code>
<code> </code><code>import</code> <code>collections</code>
<code> </code><code>File</code> <code>"/home/user/collections.py"</code><code>, line </code><code>4</code><code>, </code><code>in</code> <code><module></code>
<code> </code><code>c </code><code>=</code> <code>collections.Counter()</code>
<code>AttributeError: </code><code>'module'</code> <code>object</code> <code>has no attribute </code><code>'Counter'</code>
抛出异常,明明在解释器里面可以正常导入使用啊,怎么会提示没Counter属性呢,问题就出现你的文件名与导入的模块名重名,导致程序import了这个文件,上面讲过文件名就是模块名。所以文件名不要与引用的模块名相同。
还有一个使用方法也说明下,使用as关键字设置模块别名,这样使用中就不用输入那么长的模块名了,按照上面的例子,把名字先改成collections1.py,做测试:
<code>import</code> <code>collections as cc</code>
<code>c </code><code>=</code> <code>cc.Counter()</code>
<code># python collections1.py</code>
<code>Counter({</code><code>'l'</code><code>: </code><code>3</code><code>, </code><code>'o'</code><code>: </code><code>2</code><code>, </code><code>'!'</code><code>: </code><code>1</code><code>, </code><code>' '</code><code>: </code><code>1</code><code>, </code><code>'e'</code><code>: </code><code>1</code><code>, </code><code>'d'</code><code>: </code><code>1</code><code>, </code><code>'H'</code><code>: </code><code>1</code><code>, </code><code>'r'</code><code>: </code><code>1</code><code>, </code><code>'w'</code><code>: </code><code>1</code><code>})</code>
<code></code>
本文转自 李振良OK 51CTO博客,原文链接:http://blog.51cto.com/lizhenliang/1866390,如需转载请自行联系原作者