簡體   English   中英

模塊“鴨子打字”的陷阱?

[英]Module “duck typing” pitfalls?

我剛剛開始嘗試一種我命名的新技術(至少目前是這樣)“模塊鴨打字”。

例:

主模塊

import somepackage.req  ## module required by all others
import abc
import Xyz

模塊abc

__all__=[]

def getBus():
    """ Locates the `req` for this application """
    for mod_name in sys.modules:
        if mod_name.find("req") > 0:
            return sys.modules[mod_name].__dict__["Bus"]
    raise RuntimeError("cannot find `req` module")

Bus=getBus()

在模塊abc我不需要顯式import req :它可以在包層次結構中的任何位置。 當然這需要紀律...

使用這種技術,可以很容易地在層次結構中重新定位軟件包。

有陷阱等我嗎? 例如,移至Python 3K

更新 :經過更多測試之后,我決定返回直接在sys.path插入包依賴項的功能。

可能導入的所有模塊都包含“ req”,並且您不知道這實際上是您要查找的模塊:

>>> import urllib.request
>>> import tst
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "tst.py", line 12, in <module>
    Bus=getBus()
  File "tst.py", line 9, in getBus
    return sys.modules[mod_name].__dict__["Bus"]
KeyError: 'Bus'

包的全部要點是存在用於模塊層次結構的名稱空間。 如果用戶恰巧導入某個碰巧包含名稱沖突的模塊的庫,則“從任何軟件包中”查找模塊名稱只會導致您的代碼隨機中斷。

此技術很危險且容易出錯。 它可以與您的測試一起使用,直到有人導入新的something.req並得到一個令人困惑的,遙不可及的錯誤為止。 (這是最好的情況;當前的實現將在許多其他模塊上跳轉。)如果重組包,那么在不使用魔術的情況下以自動化方式修改代碼就很容易了。 Python使做各種神奇的,動態的事情成為可能,但這並不意味着我們應該這樣做。

我認為這更像鴨子打字。 我還建議使用比“公交車”更獨特的標識符

def getBus():
    """ Locates the Bus for this application """
    for mod in sys.modules.values():
        if hasattr(mod, 'Bus') and type(mod.Bus) is...: # check other stuff about mod.Bus
            return mod.Bus
    raise RuntimeError("cannot find Bus")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM