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

Her biri farklı argüman numaraları ve isimleri olan 'foo' gibi düzinelerce işleve sahibim. Bu fonksiyonların geri dönüş değerlerini elde edebilmem ve onlara sadece pformat gibi tek bir ekstra işlem yapmanın yaygın bir yolu var mı?Python'da yeni işlev tanımlamaksızın bir işlevin dönüş değerini değiştirmek mümkün mü?

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

Ama sonra yeni işlev 'sarıcı' argümanı sayısında, örneğin eski bir 'fonksiyon', farklıdır, 'sarıcı:

Evet ben sadece aşağıdaki gibi yeni bir fonksiyon üretebilir 'sadece 2 args -' arg 've' kw 'var, ama' func '' a ',' b ',' c 'gibi birçok args olabilir.

Sadece dönüş değeriyle oynamak istiyorum, her şey hala kalmalı, mümkün mü?

Teşekkürler!

Güncelleme Nihayet bu sorun decorator modülü kullanarak çözüldü ve şu yama edildi: Bu yama size sınırlı yöntemleri dekore sağlar

--- /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(

, sadece ilk 'self' argümanı uzakta atar, kullanımı decorator.decorator aynı kalır, şu anda hiçbir kötü etki bulunamadı.

örnek kod:

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

Bu yöntem aşırı yükleme mi? – Tauquir

+0

BTW Python, yöntem aşırı yüklenmesini desteklemiyor. – Tauquir

+0

İşlevlerinizi "pprint.pformat" dizeleriyle değiştirmek için işlevlerinizi değiştirmek aslında gerçekten çok kötü bir fikirdir (tm). Yapma. Yap. O. –

cevap

3

:

"Ama sonra yeni işlev 'sarıcı' örneğin, eskisinin 'fonk' farklıdır, >> argüman sayısının, 'sarıcı' sadece 2 vardır args - 'arg' ve 'kw', ancak 'func', 'a', 'b', 'c' gibi çok sayıda args içerebilir.

bir imza-koruyarak dekoratörler oluşturmanıza olanak sağlar decorator modülünü kullanabilirsiniz.

+0

+1 dekoratör modülünden bahseder. Bu gerçekten güçlü. Ayrıca [Venusian] (http://pypi.python.org/pypi/venusian) dekoratörler ile uğraşırken faydalı olabilir. –

+0

dekoratör modülü neredeyse problemleri çözüyor, ancak bağlı veya ilişkisiz yöntemlerle çalışmıyor gibi görünüyor. "Ayrıca, bir yöntemi süsleyebildiğinizi, ancak yalnızca eğer önce bir bağlanmış veya bağlanmamış bir yöntem haline gelirse, yani sınıfın içinde ...." olduğuna dikkat edin, bu yüzden kaynak kodunda değişiklik yapmadan bir sınıfın bazı yöntemlerini dekore etmek istiyorsanız görebildiğim kadarıyla. – jaimechen

2

süsleyiciler.

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

Bu, @ pformat_this değil mi? –

+2

@ S.Loot: functools.wrap bir imza koruyan dekoratörler değildir, sadece _ _name_ _ ve _ _doc_ _ – mouad

2

Dekoratörler aslında istemediklerinizle aynıdır.

Merak ederek, python 2.7 için buna baktım ve Callable tipleri altında>a wealth of meta information available for user defined functions olduğunu öğrendim -> Kullanıcı tanımlı işlevler. Ne yazık ki, iade edilen değer hakkında bir şey yok.

Dahili türler -> Kod nesneleri altında, the same page numaralı fonksiyondan bir kod nesnesi aracılığıyla erişebileceğiniz dahili bir tür de vardır. Bu içsel türlerin esasen API stabilitesine dair herhangi bir söz verilmemesine rağmen, iade edilen değere ilişkin olarak yazılabilir bir şey yok gibi görünmektedir.

Doğrudan yapabileceğiniz bir şey olsaydı, burada olurdu diye düşünüyorum. Umarım bir başkasının sana daha iyi şansı vardır. Sorunun Hakkında

İlgili konular