** kwargs bir antipattern mi?


16

Dahili kod tabanımızda kütüphanelerimizi dahili olarak çağıran çok fazla kodumuz var - bu kütüphaneler genellikle çok fazla argümana sahiptir (matplotlib'i düşünün) ve kodumuz genellikle sadece belirli bir görevi yerine getirir ve **kwargsçağrılan bir sonraki işleve geçer .

Örneğin:

def our_method(dataframe, **kwargs):
    result = do_something_with_data(dataframe)
    external_module.draw(result, **kwargs)

İken **kwargsbizim yöntem bildiriminde tüm parametreleri tekrarlamaktan önler bizi, o da son derece yapar çağrılırken hangi opak argümanlar geçerlidir our_methodı denir hangi yöntemi bilmek zorunda, sık sık bilmek istemediğiniz -.

Bu konudaki görüşünüz nedir?

Yanıtlar:


16

Kodunuz geliştiriciler tarafından nasıl kullanılıyor? Başka bir deyişle, hangi argümanların ve nasıl kullanılması gerektiğini belirlemek için tam olarak ne yaparlar?

  • Kodunuzdan otomatik olarak oluşturulan belgelere güveniyorlarsa ve jeneratörün ne yapacağına dair hiçbir fikri yoksa **kwargs, bu gerçekten sorunludur. Argüman listesini ve bunların dokümantasyondaki anlamlarını bulmak yerine, “ bazı argümanlar alır” belirsizleri dışında kesinlikle hiçbir bilgileri yoktur .

    Bu sorun muhtemelen, yöntemi el ile belgeleyerek ve otomatik olarak oluşturulan belgeleri değiştirerek çözülebilir. Bu, yöntemin uygulayıcısı tarafından fazladan çalışma gerektirir, ancak kodun (ve belgelerinin) yazıldığından çok daha sık okunduğunu unutmayın.

  • Kod kendi dokümanlarıysa, yöntemi kullanan geliştiricilerin **kwargsiki ek adıma ihtiyacı vardır: aslında aradığı diğer yöntemi bulmak için sadece yöntemin imzasına değil, aynı zamanda gerçek uygulamasına da bakmaları gerekir. Sonra nihayet aradıklarını bulmak için bu diğer yönteme gitmeleri gerekiyor.

    Bu çok fazla çaba gerektirmez, ancak yine de çaba tekrar tekrar tekrarlanmalıdır. En kötü yanı, dokümantasyon ekleyerek onlara yardımcı olamamanızdır: yönteminizi yorumluyorsanız, gerçek argümanları listelerseniz, yöntem çağrılarınızın sonraki sürümünün farklı argümanlara sahip olma riski yüksektir ve dokümantasyonunuz modası geçmiş olmalı, çünkü kimse güncel tutulması gerektiğini hatırlamayacak.

Benim tavsiyem **kwargssadece kapsamı kısıtlı yöntemlere güvenmektir . _Sınıfta birkaç yerde kullanılan özel yöntemler (ve Python bağlamında özel olarak ifade etmek gerekirse), örneğin iyi adaylardır. Öte yandan, kod tabanı üzerindeki düzinelerce sınıf tarafından kullanılan yöntemler çok kötü adaylardır.

Sonuçta, yazdığınız yöntem içinde çağırdığınız bir yöntemin argümanlarını yeniden yazmak çok fazla çaba sarf etmemelidir. Umarım, çoğu yöntem altı ila sekizden fazla argüman almaz ve eğer yaparlarsa, kodu yeniden düzenlememeniz gerekip gerekmediğini kendinize sorun. Her durumda:

  • Metodunuzda argümanları açık yapmak çok çaba gerektirmez,

  • Daha sonra, argümanları yine de doğrulamak isteyebilirsiniz (argümanları açık hale getirmek için sadece bu noktaya güvenirseniz, YAGNI'yi ihlal edersiniz).


Bu yanıtı gerçekten seviyorum ve bunun iyi bir yanıt olduğunu düşünüyorum. Ne yazık ki, kodumuzun çoğunda bu modeli kullanan birçok genel yöntem var. Ama şimdi onu değiştirmemiz gerektiğine dair argümanlarım var (ve matplotlib'i düşürdüm, hiç bir zaman daha hantal bir "arayüz" görmedim ..)
Christian Sauer

3

Sonraki düzey işlevinde __doc__ varsa, __doc__ öğesini yeni işlevinize kopyalayabilirsiniz.

Örneğin:

def a(x):
    """This function takes one parameter, x, and does nothing with it!"""
    pass

def b(**kwargs):
    a(**kwargs)

b.__doc__=a.__doc__

Bu, özyinelemeli olarak uygulanabilir ve bir dekoratör tarafından uygulanabilir (bunu zaten toplu olarak yapıyorsanız faydalı olabilir). __Doc__ dizesi de sonuna daha fazlasını eklemek için değiştirilebilir. Bu, gösterilen parametrelerin hala kwarg olacağı anlamına gelir, ancak en azından yardımda gerçek parametreleri açıklayan belgeler vardır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.