Python'da ipucu ile varsayılan parametre değeri ekleme


236

Ben böyle bir işlevi varsa:

def foo(name, opts={}):
  pass

Ve parametrelere tip ipuçları eklemek istiyorum, nasıl yaparım? Kabul ettiğim yol bana bir sözdizimi hatası veriyor:

def foo(name: str, opts={}: dict) -> str:
  pass

Aşağıdaki sözdizimi hatası atmaz, ancak bu durumu ele almanın sezgisel bir yolu gibi görünmemektedir:

def foo(name: str, opts: dict={}) -> str:
  pass

typingDokümanlarda veya Google aramada hiçbir şey bulamıyorum .

Düzenleme: Varsayılan bağımsız değişkenlerin Python'da nasıl çalıştığını bilmiyordum, ancak bu soru uğruna yukarıdaki örnekleri koruyacağım. Genel olarak aşağıdakileri yapmak çok daha iyidir:

def foo(name: str, opts: dict=None) -> str:
  if not opts:
    opts={}
  pass

4
Son işlev doğru yoldur. Bu scaladilin de yaptığı gibi.
İsrail Unterman

14
değiştirilebilir bir varsayılan türünüz var - bu sorunlara yol açacaktır
noɥʇʎԀʎzɐɹƆ

güncelleme cevabımı görmek, @josh
noɥʇʎԀʎzɐɹƆ

@ noɥʇʎԀʎzɐɹƆ Kullanmıyorsanız, örneğin notlama gibi değil. : P
Mateen Ulhaq

Yanıtlar:


281

İkinci yolunuz doğru.

def foo(opts: dict = {}):
    pass

print(foo.__annotations__)

bu çıktılar

{'opts': <class 'dict'>}

O listelenmeyen olduğu doğrudur PEP 484 , ancak tip tavsiyeleri PEP 3107. belgelenen işlevi ek açıklamalar, bir uygulama olan sözdizimi bölümü bu şekilde fonksiyon ek açıklamaları ile çalışır o anahtar kelime argümanları temizlemek yapar.

Değişken anahtar kelime argümanlarını kullanmamanızı şiddetle tavsiye ederim. Daha fazla bilgi burada .


1
Bkz. Legacy.python.org/dev/peps/pep-3107/#syntax . Tür ipucu yalnızca işlev ek açıklamalarının bir uygulamasıdır.
chepner

@ chepner doğru. PEP 3107'nin anahtar kelime argümanları hakkında bir şeyleri olduğunu bilmiyordu.
noɥʇʎԀʎzɐɹƆ

2
Vay canına, Python'daki değişken varsayılan argümanlar hakkında bilmiyordum ... özellikle varsayılan argümanların farklı çalıştığı Javascript / Ruby'den geliyor. Bu konuda SO hakkında zaten söylenenleri yeniden şekillendirmeyeceğim, beni ısırmadan önce bunu öğrendiğime sevindim. Teşekkürler!
josh

6
Her zaman {} veya [] gibi değişken bir tür yerine varsayılan bir nesne ya da derin bir kopya olmadan bu nesneye mutasyonlar olarak yinelemeler arasında kalmayacak hiçbiri kullanmam tavsiye edildi.
MrMesees

2
Değişken anahtar kelime argümanları ile yeterli fonksiyonları tanımlayın ve yaşam seçimlerinizi sorgulayan 4 saatlik bir hata ayıklama oturumuna geri dönüp bakmanız sadece bir zaman meselesidir
Joseph Sheedy

20

Eğer kullanıyorsanız yazmaya (Python 3.5 tanıtılan) kullanabilirsiniz typing.Optionalnerede, Optional[X]eşdeğerdir Union[X, None]. İçin açık değerine Noneizin verildiğini belirtmek için kullanılır . Gönderen typing.Optional :

def foo(arg: Optional[int] = None) -> None:
    ...

2
İçinde tür ipucu bulunmayan anahtar kelime argümanları için olduğu gibi boşluk =içinde boşluk olmamalı mı Optional[int] = None?
actual_panda

7

Son zamanlarda bu tek astarı gördüm:

def foo(name: str, opts: dict=None) -> str:
    opts = {} if not opts else opts
    pass

Merhaba @Kirkalicious, Cevabınız için teşekkürler. Nasıl çalıştığını açıklayabilir misiniz?
Nathan

1
Varsayılan parametre olarak iletilen boş dikt, her çağrı için aynı diktendir. Bu nedenle işlev onu değiştirirse, bir sonraki seferde varsayılan değer son kez değiştirilen değer olacaktır. NoneVarsayılan ayarı yapmak ve ardından yöntemin içini kontrol etmek, yöntem her çağrıldığında yeni bir diksiyon atayarak bu sorunu önler.
Ian Goldby
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.