Dekoratörler fonksiyonlardır sonuç dizesini döndürmeye çalışıyor "str değil çağrılabilir" diyerek bana bir hata verir Bu dönen işlevler. "Bir parametreyi dekoratöre geçirirken" aslında yaptığınız şey bir dekoratör döndüren bir işlevi çağırmaktır. Yani decAny()
, bir işlevi döndüren bir işlevi döndüren bir işlev olmalıdır.
Böyle görünecektir:
import functools
def decAny(tag):
def dec(f0):
@functools.wraps(f0)
def wrapper(*args, **kwargs):
return "<%s> %s </%s>" % (tag, f0(*args, **kwargs), tag)
return wrapper
return dec
@decAny('xxx')
def test2():
return 'test1XML'
Örnek: asıldığın sorunla sabitleme ek olarak ben de biraz *args
ekleyerek kod geliştirilmiş
>>> print(test2())
<xxx> test1XML </xxx>
Not olduğunu
ve Sarma işlevine argümanlar olarak
**kwargs
ve dekoratörün iç kısmına
f0
çağrılarını iletme. Bu, herhangi bir sayıdaki konumsal veya adlandırılmış argümanı kabul eden bir işlevi süsleyebilmenizi sağlar ve yine de doğru şekilde çalışmaya devam eder.
Burada yaklaşık functools.wraps()
kadar okuyabilir:
http://docs.python.org/2/library/functools.html#functools.wraps
bu konuda Şöyle düşünün 'test2'yi dekore etmek için decAny (' xxx ') 'diyorsunuz. Ama "decAny" bir işlev alır, 'f0', bir dize değil. Yani açıkça belli bir noktada, 'f0()' 'xxx'' adını vermeye çalışacaktır. – abarnert
Tamam, ama hiçbir parametresi olmayan bir dekoratörde olduğu gibi, derleyici, ilk parametrenin istemci işlevi olduğunu neden varsaymıyor ... – ZEE
Bu bir parametre meselesi değil. Eğer @ decAny' varsa, bu sadece decAny'yi bir dekoratör olarak kullanıyor. Ama eğer @decAny() 'e sahipseniz," decAny "yi dekorasyona geçmeden önce, '@decAny (' xxx ')' olduğu gibi çağırırsınız. (Aynen fonksiyonlar olarak değerleri iletmek, onları çağırmak yerine değişkenler, vb. Depolamak gibi.) – abarnert