<dd id="sga4y"><optgroup id="sga4y"></optgroup></dd>
<nav id="sga4y"><code id="sga4y"></code></nav>
  • <optgroup id="sga4y"></optgroup>

    9.2. 包

    實際上解析一個 XML 文檔是很簡單的:只要一行代碼。但是,在你接觸那行代碼前,需要暫時岔開一下,討論一下包。

    例 9.5. 載入一個 XML 文檔 (偷瞥一下)

    >>> from xml.dom import minidom 1
    >>> xmldoc = minidom.parse('~/diveintopython/common/py/kgp/binary.xml')
    1 這個語法你之前沒有見過。它看上去很像我們熟知的 from module import,但是"." 使得它好像不只是普通的 import 那么簡單。事實上,xml 稱為包,domxml 中嵌套的包,而 minidomxml.dom 中的模塊。

    聽起來挺復雜的,其實不是。看一下確切的實現可能會有幫助。包不過是模塊的目錄;嵌套包是子目錄。一個包 (或一個嵌套包) 中的模塊也只是 .py 文件罷了,永遠都是,只是它們是在一個子目錄中,而不是在你的 Python 安裝環境的主 lib/ 目錄下。

    例 9.6. 包的文件布局

    Python21/           Python 安裝根目錄 (可執行文件的所在地)
    |
    +--lib/             庫目錄 (標準庫模塊的所在地)
       |
       +-- xml/         xml包 (實際上目錄中還有其它東西)
           |
           +--sax/      xml.sax包 (也只是一個目錄)
           |
           +--dom/      xml.dom包 (包含 minidom.py)
           |
           +--parsers/  xml.parsers包 (內部使用)

    所以你說 from xml.dom import minidomPython 認為它的意思是“xml 目錄中查找 dom 目錄,然后在這個目錄 中查找 minidom 模塊,接著導入它并以 minidom 命名 ”。但是 Python 更聰明;你不僅可以導入包含在一個包中的所有模塊,還可以從包的模塊中有選擇地導入指定的類或者函數。語法都是一樣的; Python 會根據包的布局理解你的意思,然后自動進行正確的導入。

    例 9.7. 包也是模塊

    >>> from xml.dom import minidom         1
    >>> minidom
    <module 'xml.dom.minidom' from 'C:\Python21\lib\xml\dom\minidom.pyc'>
    >>> minidom.Element
    <class xml.dom.minidom.Element at 01095744>
    >>> from xml.dom.minidom import Element 2
    >>> Element
    <class xml.dom.minidom.Element at 01095744>
    >>> minidom.Element
    <class xml.dom.minidom.Element at 01095744>
    >>> from xml import dom                 3
    >>> dom
    <module 'xml.dom' from 'C:\Python21\lib\xml\dom\__init__.pyc'>
    >>> import xml                          4
    >>> xml
    <module 'xml' from 'C:\Python21\lib\xml\__init__.pyc'>
    1 這里你正從一個嵌套包 (xml.dom)中導入一個模塊 (minidom)。結果就是 minidom 被導入到了你 (程序) 的命名空間中了。要引用 minidom 模塊中的類 (比如 Element),你必須在它們的類名前面加上模塊名。
    2 這里你正從一個來自嵌套包 (xml.dom) 的模塊 (minidom) 中導入一個類 (Element)。結果就是 Element 直接導入到了你 (程序) 的命名空間中。注意,這樣做并不會干擾以前的導入;現在 Element 類可以用兩種方式引用了 (但其實是同一個類)。
    3 這里你正在導入 dom 包 (xml 的一個嵌套包),并將其作為一個模塊。一個包的任何層次都可以視為一個模塊,一會兒就會看到。它甚至可以擁有自己的屬性和方法,就像你在前面看到過的模塊。
    4 這里你正在將根層次的 xml 包作為一個模塊導入。

    那么如何才能導入一個包 (它不過是磁盤上的一個目錄) 并使其成為一個模塊 (它總是在磁盤上的一個文件) 呢?答案就是神奇的 __init__.py 文件。你明白了吧,包不只是目錄,它們是包含一個特殊文件 __init__.py 的目錄。這個文件定義了包的屬性和方法。例如,xml.dom 包含了 Node 類,它在xml/dom/__init__.py中有所定義。當你將一個包作為模塊導入 (比如從 xml 導入 dom) 的時候,實際上導入了它的 __init__.py 文件。

    注意
    一個包是一個其中帶有特殊文件 __init__.py 的目錄。__init__.py 文件定義了包的屬性和方法。其實它可以什么也不定義;可以只是一個空文件,但是必須要存在。如果 __init__.py 不存在,這個目錄就僅僅是一個目錄,而不是一個包,它就不能被導入或者包含其它的模塊和嵌套包。

    那為什么非得用包呢?嗯,它們提供了在邏輯上將相關模塊歸為一組的方法。不使用其中帶有 saxdomxml 包,作者也可以選擇將所有的 sax 功能放入 xmlsax.py中,并將所有的 dom 功能放入 xmldom.py中,或者干脆將所有東西放入單個模塊中。但是這樣可能不實用 (寫到這兒時,XML 包已經超過了 3000 行代碼) 并且很難管理 (獨立的源文件意味著多個人可以同時在不同的地方進行開發)。

    如果你發現自己正在用 Python 編寫一個大型的子系統 (或者,很有可能,當你意識到你的小型子系統已經成長為一個大型子系統時),你應該花費些時間設計一個好的包架構。它是 Python 所擅長的事情之一,所以應該好好利用它。

    97av