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

    6.4. 使用 sys.modules

    與其它任何 Python 的東西一樣,模塊也是對象。只要導入了,總可以用全局 dictionary sys.modules 來得到一個模塊的引用。

    例 6.12. sys.modules 介紹

    >>> import sys                          1
    >>> print '\n'.join(sys.modules.keys()) 2
    win32api
    os.path
    os
    exceptions
    __main__
    ntpath
    nt
    sys
    __builtin__
    site
    signal
    UserDict
    stat
    1 sys 模塊包含了系統級的信息,像正在運行的 Python 的版本 (sys.versionsys.version_info),和系統級選項,像最大允許遞歸的深度 (sys.getrecursionlimit()sys.setrecursionlimit())。
    2 sys.modules 是一個字典,它包含了從 Python 開始運行起,被導入的所有模塊。鍵字就是模塊名,鍵值就是模塊對象。請注意除了你的程序導入的模塊外還有其它模塊。Python 在啟動時預先裝入了一些模塊,如果你在一個 Python IDE 環境下,sys.modules 包含了你在 IDE 中運行的所有程序所導入的所有模塊。

    下面的例子展示了如何使用 sys.modules

    例 6.13. 使用 sys.modules

    >>> import fileinfo         1
    >>> print '\n'.join(sys.modules.keys())
    win32api
    os.path
    os
    fileinfo
    exceptions
    __main__
    ntpath
    nt
    sys
    __builtin__
    site
    signal
    UserDict
    stat
    >>> fileinfo
    <module 'fileinfo' from 'fileinfo.pyc'>
    >>> sys.modules["fileinfo"] 2
    <module 'fileinfo' from 'fileinfo.pyc'>
    1 當導入新的模塊,它們加入到 sys.modules 中。這就解釋了為什么第二次導入相同的模塊時非常的快:Python 已經在 sys.modules 中裝入和緩沖了,所以第二次導入僅僅對字典做了一個查詢。
    2 一旦給出任何以前導入過的模塊名 (以字符串方式),通過 sys.modules 字典,你可以得到對模塊本身的一個引用。

    下面的例子將展示通過結合使用 __module__ 類屬性和 sys.modules dictionary 來獲取已知類所在的模塊。

    例 6.14. __module__ 類屬性

    >>> from fileinfo import MP3FileInfo
    >>> MP3FileInfo.__module__              1
    'fileinfo'
    >>> sys.modules[MP3FileInfo.__module__] 2
    <module 'fileinfo' from 'fileinfo.pyc'>
    1 每個 Python 類都擁有一個內置的類屬性 __module__,它定義了這個類的模塊的名字。
    2 將它與 sys.modules 字典復合使用,你可以得到定義了某個類的模塊的引用。

    現在準備好了,看看在樣例程序 第 5 章 sys.modules 介紹的 fileinfo.py 中是如何使用的。這個例子顯示它的一部分代碼。

    例 6.15. fileinfo.py 中的 sys.modules

        def getFileInfoClass(filename, module=sys.modules[FileInfo.__module__]):       1
            "get file info class from filename extension"                             
            subclass = "%sFileInfo" % os.path.splitext(filename)[1].upper()[1:]        2
            return hasattr(module, subclass) and getattr(module, subclass) or FileInfo 3
    1 這是一個有兩個參數的函數;filename 是必須的,但 module可選的并且 module 的缺省值包含了 FileInfo 類。這樣看上去效率低,因為你可能認為 Python 會在每次函數調用時計算這個 sys.modules 表達式。實際上,Python 僅會對缺省表達式計算一次,是在模塊導入的第一次。正如后面我們會看到的,我們永遠不會用一個 module 參數來調用這個函數,所以 module 的功能是作為一個函數級別的常量。
    2 我們會在后面再仔細研究這一行,在我們了解了 os 模塊之后。那么現在,只要相信 subclass 最終為一個類的名字就行了,像 MP3FileInfo
    3 你已經了解了 getattr,它可以通過名字得到一個對象的引用。hasattr 是一個補充性的函數,用來檢查一個對象是否具有一個特定的屬性;在本例中,用來檢查一個模塊是否有一個特別的類 (然而它可以用于任何類和任何屬性,就像 getattr)。用英語來說,這行代碼是說,“If this module has the class named by subclass then return it, otherwise return the base class FileInfo (如果這個模塊有一個名為 subclass 的類,那么返回它,否則返回基類 FileInfo)”。

    進一步閱讀

    97av