在Python中是否可以不定义新函数而修改函数的返回值?
def foo(a, b, c = 0):
return a+b
我有很多像'foo'这样的函数,它们的参数数量和名称都不一样。我想知道有没有一种通用的方法,可以获取这些函数的返回值,然后对它们进行一次简单的操作,比如格式化输出。
当然,我可以像下面这样生成一个新的函数:
func = ... # func can be got using getattr by name
def wrapper(*arg, **kw):
data = func(*arg, **kw)
return pprint.pformat(data)
return wrapper
但是,这个新函数'wrapper'和旧函数'func'是不同的,比如在参数数量上,'wrapper'只有两个参数——'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(
这个补丁允许你装饰绑定的方法,它只是把第一个'self'参数丢掉,使用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
jaime@westeros:~/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
>>>
3 个回答
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
2
装饰器其实就是你不想要的东西。
出于好奇,我查了一下Python 2.7,发现关于用户自定义函数有很多元信息可以参考,具体在可调用类型下的用户定义函数部分。不过,遗憾的是,关于返回值的内容并没有找到。
你还可以通过函数访问一个内部类型,叫做代码对象,具体信息可以在同一页面的内部类型下找到。虽然这些内部类型基本上没有保证会稳定,但在返回值方面似乎也没有什么可以写的东西。
我感觉如果有什么可以直接操作的东西,应该就在这里。希望其他人能帮你找到更好的解决办法。
4
关于你的问题:
“但是新的函数 'wrapper' 和旧的函数 'func' 不一样,比如在参数数量上,'wrapper' 只有两个参数——'arg' 和 'kw',而 'func' 可能有很多参数,比如 'a'、'b'、'c'。”
你可以使用decorator模块,这个模块可以帮助你创建保留函数签名的装饰器。