2012-08-13 46 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