2012-08-13 44 views
1

我正在使用requests模塊,但問題更爲通用。在模塊方法前自動執行代碼

有沒有辦法在從導入的模塊調用方法之前自動執行代碼?

這會使編寫代碼更容易。目前我擔心敲打友好的網絡服務,所以除非我能找到答案,否則我必須實施自己的控制。


我想通過這樣做:

import requests as requests2 

...然後在某個點上進一步的代碼,定義一個requests()功能,具有特殊的參數或一些神奇的未被發現的語法。在運行自己的代碼後,特殊醬會將方法調用轉發給實模塊,其別名爲requests2

可以這樣做嗎?

回答

2

你的意思是像添加裝飾到另一個模塊中的每個功能?你可以模擬與類:

class RequestsProxy(object): 
    def __init__(self): 
     self.special_sauce_decorator = special_sauce_indeed() 
     self._requests = __import__("requests") 

    def __getattr__(self, attrname): 
     val = getattr(self._requests, attrname) 
     if callable(val): 
      return self.special_sauce_decorator(val) 
     return val 

用法示例:

>>> def special_sauce_indeed(): 
     def decorator(f): 
       def wrapped(*args, **kwargs): 
         print 'wrapped' 
         return f(*args, **kwargs) 
       return wrapped 
     return decorator 

>>> class OsProxy(object): 
     def __init__(self): 
      self.special_sauce_decorator = special_sauce_indeed() 
      self._requests = __import__("os") 

     def __getattr__(self, attrname): 
      val = getattr(self._requests, attrname) 
      if callable(val): 
       return self.special_sauce_decorator(val) 
      return val 


>>> os = OsProxy() 
>>> os.listdir(".") 
wrapped 
['DLLs', 'Doc', 'faiojerf.py', 'func_counter_test.py', 'include', 'inet_time.py', 'kcol.py', 'Lib', 'libs', 'LICENSE.txt', 'memoize_test.py', 'minpy.py', 'NEWS.txt', 'numpy-wininst.log', 'paren_test.py', 'PIL-wininst.log', 'psycopg2-wininst.log', 'python.exe', 'pythonw.exe', 'pywin32-wininst.log', 'README.txt', 'Removenumpy.exe', 'RemovePIL.exe', 'Removepsycopg2.exe', 'Removepywin32.exe', 'Removescipy.exe', 'Removesetuptools.exe', 'scipy-wininst.log', 'Scripts', 'setuptools-wininst.log', 'slots.py', 'so1.py', 'staticvar.py', 'summing.py', 'taojiwjiot.,py', 'tcl', 'templol.py', 'test.py', 'thunkify_test.py', 'TicketNumberGenerator.py', 'Tools', 'w9xpopen.exe', 'wordcount.py'] 
+0

是的,我認爲這就是我的意思,謝謝。 – jon 2012-08-13 22:54:07

+0

Neato!我不會做所有的異常檢查 - 'getattr'將會引發默認的異常(並且可以說'special_sauce_decorator'應該處理非可調用的事件)。 EAFP和所有這些=) – katrielalex 2012-08-13 23:01:07

+1

歐洲魚類病理學家協會?哦,[gotcha](http://docs.python.org/glossary.html#term-eafp)。好點子 – Claudiu 2012-08-13 23:16:56

3

你有正確的想法。爲請求執行任何想要的操作,然後將方法調用轉發給實際的requests模塊。例如

class RequestProxy(object): 
    def __init__(self): 
     import requests as _requests 
     self._requests = _requests 

    def __getattribute__(self, attr): 
     run_custom_code() 
     return getattr(self._requests, attr) 

requests = RequestProxy() 
+0

精彩。謝謝,我很感激。 – jon 2012-08-13 22:54:59

+0

有一件事,你有'__getattribute__',而Claudiu有'__getattr__'。我沒有提到一個Python版本...道歉。 – jon 2012-08-13 22:56:37

+0

@Jon它不是Python版本的東西 - [他們做不同的事情](http://stackoverflow.com/questions/4295678/understanding-the-difference-between-getattr-and-getattribute)=) – katrielalex 2012-08-13 23:02:04