2010-10-22 47 views
5
def foo(a, b, c = 0): 
    return a+b 

我有几十个像'foo'这样的函数,它们都有不同的参数号和名字。有没有一种常用的方法可以获得这些函数的返回值,并且只需要像pformat这样的额外操作呢?是否有可能修改一个函数的返回值,而无需在python中定义新的函数?

是的,我可以只产生像下面这样的新功能:

func = ... # func can be got using getattr by name 
def wrapper(*arg, **kw): 
    data = func(*arg, **kw) 
    return pprint.pformat(data) 
return wrapper 

但随后的新功能“包装”是旧的“功能”,例如不同,在参数号,“包装'只有2个参数 - 'arg'和'kw',但'func'可能有很多参数,如'a','b','c'。

我只想玩回归价值,其他一切都应该保持不变,这有可能吗?

谢谢!

更新 最后这个问题是使用decorator模块解决,下面的补丁:

--- /home/jaime/cache/decorator-3.2.0/src/decorator.py 2010-05-22 23:53:46.000000000 +0800 
+++ decorator.py 2010-10-28 14:55:11.511140589 +0800 
@@ -66,9 +66,12 @@ 
      self.name = '_lambda_' 
      self.doc = func.__doc__ 
      self.module = func.__module__ 
-   if inspect.isfunction(func): 
+   if inspect.isfunction(func) or inspect.ismethod(func): 
       argspec = inspect.getargspec(func) 
       self.args, self.varargs, self.keywords, self.defaults = argspec 
+    if inspect.ismethod(func): 
+     self.args = self.args[1:] # Remove the useless 'self' arg 
+     argspec = inspect.ArgSpec(self.args, self.varargs, self.keywords, self.defaults) 
       for i, arg in enumerate(self.args): 
        setattr(self, 'arg%d' % i, arg) 
       self.signature = inspect.formatargspec(

这个补丁可以让你装饰界的方法,它只是抛出的第一个“自我”的说法了,用法decorator.decorator保持不变,现在没有发现任何不良效果。

示例代码:

def __getattr__(self, attr): 
    def pformat_wrapper(f, *args, **kw): 
     data = f(*args, **kw) 
     return pprint.pformat(data, indent = 4) 

    method = getattr(self.ncapi, attr) 
    return decorator(pformat_wrapper, method) # Signature preserving decorating 





[email protected]:~/bay/dragon.testing/tests$ python 
Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56) 
[GCC 4.4.3] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import decorator 
>>> class A: 
... def f(self): 
...  pass 
... 
>>> a = A() 
>>> a.f 
<bound method A.f of <__main__.A instance at 0xb774a20c>> 
>>> def hello(f, *args, **kw): 
...  print 'hello' 
...  return f(*args, **kw) 
... 
>>> f1 = decorator.decorator(hello, a.f) 
>>> f1() 
hello 
>>> 
+0

方法是否重载? – Tauquir 2010-10-22 10:28:14

+0

顺便说一句Python不支持方法重载。 – Tauquir 2010-10-22 10:28:41

+0

改变你的函数来用'pprint.pformat'字符串替换可用的值实际上是一个非常糟糕的想法(tm)。别。做。它。 – 2010-10-22 10:44:46

回答

3

关于你的问题:

“但新的功能‘包装’是旧的‘功能’不同,例如,在>>数量的说法,‘包装’只有2 args - 'arg'和'kw',但'func'可能有很多>>参数,如'a','b','c'。“

可以使用decorator模块,使您能够创建一个签名保留装饰。

+0

+1来提及装饰器模块。它非常强大。另外[Venusian](http://pypi.python.org/pypi/venusian)在处理装饰器时可能会很有用。 – 2010-10-22 12:40:24

+0

修饰器模块几乎可以解决这些问题,但它似乎不适用于绑定或未绑定的方法。 “此外,请注意,您可以修饰方法,但只能在if变为绑定或未绑定的方法之前,即在类中......”,因此如果您想修饰某个类的某些方法而不修改其源代码据我所见。 – jaimechen 2010-10-25 07:47:05

2

装修。

from functools import wraps 
def pformat_this(someFunc): 
    @wraps(someFunc) 
    def wrapper(*arg, **kw): 
     data = someFunc(*arg, **kw) 
     return pprint.pformat(data) 
    return wrapper 


@pformat_this 
def foo(a, b, c = 0): 
    return a+b 
+0

不应该是'@ pformat_this'吗? – 2010-10-22 10:17:59

+2

@ S.Loot:functools.wrap不是一个保留签名的装饰器,它只是保留__name_ _和_ _doc_ _ – mouad 2010-10-22 11:59:57

2

修饰器基本上和你不想要的一样。好奇,我研究了python 2.7,发现在Callable类型 - >用户定义函数下有a wealth of meta information available for user defined functions。不幸的是,返回值没有任何关系。

还有一种内部类型,您可以通过内部类型 - >代码对象下的函数(代码对象the same page)来访问。尽管这些内部类型基本上不提供API稳定性的承诺,但就返回值而言,似乎没有任何可写的内容。

我有一种感觉,如果有任何事情你可以直接做,它会在这里。希望别人对你有更好的运气。

相关问题