2010-10-22 48 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穩定性的承諾,但就返回值而言,似乎沒有任何可寫的內容。

我有一種感覺,如果有任何事情你可以直接做,它會在這裏。希望別人對你有更好的運氣。

相關問題