2016-04-05 26 views
1

Bir dekoratör oluşturmaya ve pyinvoke@task dekoratörünün yanında kullanıyorum.Pyinvoke @task dekoratör ile çoklu dekoratör kullanmak

Bkz:eğer

<Task 'zip_files'> No idea what 'zip_files' is!

olursa olsun: Ben inv zip_files

ben çıkışını almak yürütmek komut satırından şimdi Ancak

def extract_config(func): 
    print func 

    def func_wrapper(cfg=None): 
     config = read_invoke_config(cfg) 
     return func(**config) 

    return func_wrapper 


@extract_config 
@task 
def zip_files(config): 
    import zipfile 
    ... 

, 10 önce veya @extract_config sonra gelir, ben invoke görev işlevselliği kaybettim ve işlev adını tanımıyor ..

Burada yanlış ne yapıyorum?

cevap

2

sözdizimi:

def func(): pass 
func = deco1(deco2(func)) 

Yani ilk satırda dekoratör ikinci satırda dekoratör sonra uygulanır:

@deco1 
@deco2 
def func(): pass 

için hemen hemen eşdeğer mi.

Eğer kütüphaneden kullandığınız task dekoratör bir Task nesne yerine başka bir işlevi döndürür, böylece bir sarıcı işlevi ile genel ad değiştirerek zaman dış dekoratör doğru olanı yaptığını olmayabilir. Çalıştırmak için, Task nesnesinin tüm ilgili davranışlarını taklit eden bir nesne olması için wrapper öğenize ihtiyacınız vardır (bunun ne kadar kolay veya zor olduğu hakkında hiçbir fikrim yok). Bu çalışma belki daha yakın olduğu

@task 
@extract_config 
def zip_files(config): 

, ama yine de basit bir nedenden dolayı yanlış giderse şüpheli:

daha yalındır yaklaşım dekoratörler sırasını tersine çevirmek için olabilir. extract_config dekoratörünüz, zip_files'dan farklı bir işleve sahip bir işlev döndürür (__name__ özniteliğini değiştirmek için herhangi bir çaba sarf etmemiş olan wrapper adlı işlevi döndürür), böylece Task nesnenin adı düzgün olarak bilinmez.

def extract_config(func): 
    print func 

    @functools.wraps(func) 
    def func_wrapper(cfg=None): 
     config = read_invoke_config(cfg) 
     return func(**config) 

    return func_wrapper 
:

Bunu düzeltmek için, ben sarıcı işlevi içine sarılmış fonksiyonun alakalı özellikleri kopyalamak için dekoratör içinde functools.wraps kullanarak öneririm

İlgili konular