<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            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 所擅長的事情之一,所以應該好好利用它。

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线