天天看點

第九章 Python自定義子產品及導入方法

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>&gt;&gt;&gt; </code><code>import</code> <code>test</code>

<code>&gt;&gt;&gt; test.func(</code><code>2</code><code>, </code><code>2</code><code>)</code>

<code>4</code>

<code>&gt;&gt;&gt; c </code><code>=</code> <code>test.MyClass(</code><code>2</code><code>, </code><code>2</code><code>)</code>

<code>&gt;&gt;&gt; c.method()</code>

是不是很簡單!是的,沒錯,就是這樣。

需要注意的是,test就是檔案名。另外,子產品名要能找到,我的是在目前目錄下。

有時經常from...import...,這又是啥呢,來看看:

<code>&gt;&gt;&gt; </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>"&lt;stdin&gt;"</code><code>, line </code><code>1</code><code>, </code><code>in</code> <code>&lt;module&gt;</code>

<code>NameError: name </code><code>'test'</code> <code>is</code> <code>not</code> <code>defined</code>

<code>&gt;&gt;&gt; func(</code><code>2</code><code>, </code><code>2</code><code>)</code>

<code>&gt;&gt;&gt; c </code><code>=</code> <code>MyClass(</code><code>2</code><code>, </code><code>2</code><code>)</code>

看到了吧!如果你不想把子產品裡的函數都導入,就可以這樣。一方面避免導入過多用不到的函數增加負載,另一方面引用時可不加子產品名。

如果想調用不加子產品名,也想導入所有子產品,可以這樣:

<code>&gt;&gt;&gt; </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 --&gt; 方式2 --&gt; 方式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>&gt;&gt;&gt; </code><code>import</code> <code>collections    </code>

<code>&gt;&gt;&gt; </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>&gt;&gt;&gt; </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>|  &gt;&gt;&gt; c </code><code>=</code> <code>Counter(</code><code>'abcdeabcdabcaba'</code><code>)  </code><code># count elements from a string</code>

<code>     </code><code>|  &gt;&gt;&gt; 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>|  &gt;&gt;&gt; </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>|  &gt;&gt;&gt; ''.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>|  &gt;&gt;&gt; </code><code>sum</code><code>(c.values())                 </code><code># total of all counts</code>

<code>     </code><code>|  </code><code>15</code>

<code>     </code><code>|  &gt;&gt;&gt; c[</code><code>'a'</code><code>]                          </code><code># count of letter 'a'</code>

<code>......</code>

一般裡面都是舉例說明,可快速幫助我們回憶使用方法。

2)dir()函數檢視對象屬性

這個在前面也用到過,能看到對象的方法、屬性等資訊:

<code>    </code><code>&gt;&gt;&gt; </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>&lt;module&gt;</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>&lt;module&gt;</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,如需轉載請自行聯系原作者