2011-02-17 15 views
33

Python'un ne kadar güzel göründüğünü/hissettiğini ve bunun daha temiz olabileceğini umuyorum (okunabilirlik harika).Python - super() çağrısından sonra isteğe bağlı bir kwarg'ın kullanılması gerektiği __init__'i geçersiz kılmanın en temiz yolu?

opsiyonel kwargsuper() çağrı sonrasında kullanılmak üzere bir sınıflandırma init geçersiz kılmak için isteğe bağlı bir anahtar kelime argüman kabul etmek temiz bir yolu nedir?

ben isteğe bağlı bir kullanıcı argüman kabul etmek istiyorum bir Django form var, ama argümanlar user=None biri olarak tanımlarsanız, o zaman her zamanki formu çağrı form({}) pozisyonel argüman anahtar kelime argüman user atıfta varsayar.

def __init__(self, *args, **kwargs): 
    user = None 
    if 'user' in kwargs: 
     user = kwargs.pop('user') 
    super(BaseCheckoutForm, self).__init__(*args, **kwargs) 
    if user: 
     self.prefill_from_user(user) 

Ben aradığını argümanlar görmek için gerçek Form sınıfa bakarak bu en temiz yapabilirsiniz, ancak herhangi bir şey sınıflara ile ilgili en büyük şeylerden biri:

Kodu (benim) kelimelerden daha iyi konuşur python tüm args ve kwargs toplayarak ve alt sınıflara her şeyi içine geçiriyor. Ayrıca bu, kaynakta herhangi bir değişiklik yapmaz.

def __init__(self, querydict=None, user=None): 
    super(BaseCheckoutForm, self).__init__(querydict) 
    if user: 
     self.prefill_from_user(user) 

Ama ne yazık ki var: Herhangi bir giriş için

def __init__(self, *args, **kwargs): 
    # cannot define user=None as an argument because normal usage 
    # of class expects a certain order of positional args 
    user = None 
    if 'user' in kwargs: 
     # must pop now since super()__init__ isn't expecting a user kwarg 
     user = kwargs.pop('user') 
    super(BaseCheckoutForm, self).__init__(*args, **kwargs) 
    if user: 
     self.prefill_from_user(user) 

Teşekkür!

+2

Bir ipucu: Ancak, dict.pop için varsayılan bir argüman sağlayarak kodunuzu temizlemek/kısaltabilir x None' değil 'yoluyla None'' olmadığını kontrol edin. 'x' değil' olası 'birkaç olası değerler için' 'True' (boş koleksiyonlar (dizgiler dahil), sıfır (- eşdeğer sayılar), tabii ki 'False', vb.). Aynı zamanda daha açık/okunabilir, bazıları şöyle derdi:) – delnan

+0

Bence eğer 'eğer kullanıcı:' ile daha okunabilir ve diğer değerler zaten geçerli değil (False, '', []). O zaman davamda sorun olur mu? –

+1

"Kullanıcı" olarak iletilen herhangi bir değerin, mantıksal bir "True" ile yok sayılmadığı sürece, o zaman evet, sorun değil. Bununla birlikte, birçok durumda bunun tarafından yakılabilir. Sadece farklılıkların farkında ol! –

cevap

52

Genelde sadece burada yaptığınız şeyi yapıyorum.

def __init__(self, *args, **kwargs): 
    user = kwargs.pop('user', None) 
    super(BaseCheckoutForm, self).__init__(*args, **kwargs) 
    if user is not None: 
     self.prefill_from_user(user) 
+3

Ohh, çok güzel! Pop'un ikinci bir argümanı olduğunu anlamadım. Bunu sık sık söylemediğimi söyleyebilir misin? Bu yardımcı olur! –

+5

@Yuji - Kesinlikle hoş bir özellik! 'Dict.get' için varsayılan bir değer kullanabileceğinizi unutmayın, ayrıca 'KeyError'lardan kaçınmak için. Yani 'x' içinde değilken bir KeyError'dan kaçınmak istiyorsanız, x ['a'] 'yerine x.get ('a', defaultvalue) kullanın. –

+0

Bunu kullanıyorum, evet, bu büyük bir kod temizleyici! –

İlgili konular