2010-09-22 51 views
3

我正在尋找一種在Python 2.x中使用importlib的方式來即時重寫導入模塊的字節碼。換句話說,我需要在導入期間的編譯和執行步驟之間掛鉤我自己的函數。除此之外,我希望導入功能與內置功能一樣工作。如何使用importlib重寫字節碼?

我已經做了imputil,但該圖書館並沒有涵蓋所有的情況,反正是不推薦使用。

+0

「我需要掛鉤的編制和實施步驟之間我自己的函數」是不是這個東西裝飾是?你是猴子補丁嗎?這是什麼意思? – 2010-09-22 14:08:06

+1

我相信,鑑於Michał已經無法實現它,他有一個要點。 – 2010-09-22 15:26:37

+3

我是單元測試生成器Pythoscope的作者。爲了攔截正在運行的應用程序的事件,我需要先執行一些字節碼操作。你可以在這裏看到我的實現使用imputil:http://bazaar.launchpad.net/~pythoscope-developers/pythoscope/trunk/annotate/head:/bytecode_tracer/code_rewriting_importer.py在某些情況下失敗(例如,它doesn'當涉及酸洗工作時),所以我需要一個更加防彈的解決方案。 importlib AFAIK被認爲是進口鉤子的新標準,但我對此不甚瞭解,因此也是我的問題。 – 2010-09-22 16:43:45

回答

2

有過通過importlib源代碼一看,我相信你可以在_bootstrap模塊中繼承PyLoader和覆蓋get_code

class PyLoader: 
    ... 

    def get_code(self, fullname): 
    """Get a code object from source.""" 
    source_path = self.source_path(fullname) 
    if source_path is None: 
     message = "a source path must exist to load {0}".format(fullname) 
     raise ImportError(message) 
    source = self.get_data(source_path) 
    # Convert to universal newlines. 
    line_endings = b'\n' 
    for index, c in enumerate(source): 
     if c == ord(b'\n'): 
      break 
     elif c == ord(b'\r'): 
      line_endings = b'\r' 
      try: 
       if source[index+1] == ord(b'\n'): 
        line_endings += b'\n' 
      except IndexError: 
       pass 
      break 
    if line_endings != b'\n': 
     source = source.replace(line_endings, b'\n') 

    # modified here 
    code = compile(source, source_path, 'exec', dont_inherit=True) 
    return rewrite_code(code) 

我假設你知道你在做什麼,而是代表程序員無處不在,我相信我應該說: = p

+1

是的,我知道我在做什麼,謝謝。 ;)無論如何,直到現在我才注意到importlib backport只支持一個函數,而不是整個庫。呃,回到原點... – 2010-09-23 12:29:34

相關問題