2014-03-06 58 views
2

我一直在使用sh模塊來主要執行Git命令。我遇到的問題是,sh生成子殼來完成這項工作,std輸出沒有定向到我的主Python腳本的輸出。當然,我能做到以下幾點,每個sh.git通話,就像如下:爲python創建一個不尋常的包裝sh

git = sh.git.bake(_cwd=repoPath) 
print git.fetch().stdout 
print git.log('-n=1', SHA).stdout 

但我並不想這樣做。我想打一個包裝,所以我可以在我的git電話嵌入標準輸出打印功能,所以也許是這樣,但具有相同的結果:

git = wrapper(sh.git.bake(_cwd=repoPath)) 
git.fetch() 
git.log('-n=1', SHA) 

我讀過有關Python的功能,裝飾,但我沒有一直能夠弄清楚。

+1

爲什麼不直接調用git不使用sh?或者使用[gitpython](https://pythonhosted.org/GitPython/0.3.1/intro.html)封裝器 – Mark

+0

但是我仍然對非Git的東西有同樣的問題,不是嗎? – user3385082

+0

如果你不使用sh – Mark

回答

1

像下面這樣的東西應該工作:

import functools 

class wrapper(object): 
    def __init__(self, obj): 
     self.obj = obj 

    @staticmethod 
    def _print_stdout_deco(func): 
     @functools.wraps(func) 
     def print_stdout(*args, **kwargs): 
      print func(*args, **kwargs).stdout 
     return print_stdout 

    def __getattr__(self, name): 
     f = self._print_stdout_deco(getattr(self.obj, name)) 
     setattr(self, name, f) 
     return f 

這將創建一個包裝對象,它代表所有屬性查找到在傳遞的對象時的屬性查詢時,從被包裝對象的屬性裝飾。執行打印到標準輸出然後返回。請注意,這假設來自包裝對象的所有屬性都是函數,我認爲這是sh模塊的有效假設,但我並不完全確定。如果不是這種情況,您將要檢查getattr(self.obj, name)的結果,如果它是一個函數,只傳遞給裝飾器。

+0

完美的作品!我會通過閱讀這段代碼學到很多東西 – user3385082