İşlev dönüş türü ve bağımsız değişken türleri nasıl öğrenilir?


91

Python'un ördek-yazma kavramının farkında olsam da, bazen işlevlerin argümanlarının türü veya işlevin dönüş değerinin türü ile mücadele ediyorum.

Şimdi, işlevi kendim yazarsam, türleri bilirim. Peki ya biri benim işlevlerimi kullanmak ve çağırmak isterse, türleri bilmesi nasıl beklenir? Genellikle tür bilgilerini işlevin belge dizesine koyarım (örneğin: "...the id argument should be an integer..."ve "... the function will return a (string, [integer]) tuple.")

Ama dokümandaki bilgiye bakmak (ve onu kodlayıcı olarak oraya koymak) gerçekten yapılması gerektiği gibi mi?

Düzenleme: Cevapların çoğu "evet, belge!" Bunun "karmaşık" tipler için her zaman çok kolay olmadığını düşünüyorum.
Örneğin: bir dokümantasyon dizesinde, bir işlevin formun her bir demetiyle (düğüm_kimliği, düğüm_adı, çalışma_dakika) bir demet listesi döndürdüğünü ve öğelerin sırasıyla bir dizge, dizge ve tamsayı olduğunu kısaca nasıl açıklayabilirim ?
Docstring PEP dokümantasyonu bu konuda herhangi bir talimat vermez.
Sanırım karşı argüman, bu durumda sınıfların kullanılması gerektiğidir, ancak python'u çok esnek buluyorum çünkü bu şeyleri listeler ve tuple kullanarak, yani sınıflar olmadan geçmeye izin veriyor .


2
Kısa cevap "evet" tir. Uzun cevap "evet, tabii ki" dir. Python koduna çok fazla bakıp bakmadığınızı bilmiyorum, ancak muhtemelen hangi paketleri kullandığınızı belirtmek için soruyu güncellemelisiniz , böylece sizi koda yönlendirebiliriz, böylece kitaplık kodunda işlerin nasıl yapıldığını görmek için okuyabilirsiniz. aslında şu anda kullanıyoruz.
S.Lott

@ S.Lott: Şu anda makineleştirme paketi ile mücadele ediyorum, ancak sanırım sadece (maalesef) kötü bir şekilde belgelenmiştir.
Rabarberski

6
Python'un havalı çünkü hızlı bir şekilde çok sayıda kod yazabilirsiniz ve dönüş türleri, argüman türleri, çalışma zamanı performansı, spagetti kodunuzu önümüzdeki 10 yıl boyunca kullanmak ve korumak zorunda olan kişiler gibi sıradan şeyler hakkında endişelenmenize gerek yoktur. .
jarmod

Yanıtlar:


128

2011'den beri işler biraz değişti! Artık Python 3.5'te argümanlara açıklama eklemek ve işlevinizin türünü döndürmek için kullanabileceğiniz tür ipuçları var . Örneğin bu:

def greeting(name):
  return 'Hello, {}'.format(name)

artık şu şekilde yazılabilir:

def greeting(name: str) -> str:
  return 'Hello, {}'.format(name)

Artık türleri görebileceğiniz gibi, size ve tür denetleyicinize kodunuzu araştırmanıza yardımcı olacak bir tür isteğe bağlı statik tür denetimi vardır.

Daha fazla açıklama için PyCharm blogundaki tip ipuçları hakkındaki blog gönderisine bir göz atmanızı öneririm .


Yazımlarını bir türü de Python 2.7 için önerildi unutmayın burada aynı PEP-0484 yılında. Ve PyCharm'da, en azından 2017.3 sürümünden itibaren çalışır.
viddik13

1
Tam olarak aynı tanımlı selamlama işlevi, int türünde bir nesne döndürürse, hata oluşmaz. Öyleyse, dönüş türünden açıkça bahsediyor, ancak kurala uyup farklı türde bir nesne döndürmüyorsanız, bu tür bir türün kullanımı nedir?
Arashsyh

3
@Arashsyh: Evet, haklısın, yazım ipuçları Python'u statik olarak yazılmış bir dile çevirmez, doğru türleri doğru şekilde kullanmak size kalmış. Ve bu tür ipuçları size - daha hızlı geliştirmenize, kodunuzu kendi kendinize belgelemenize veya bir şeyi karıştırdığınızda uyarı almanıza yardımcı olur. Özellikle PyCharm (veya benzer IDE) kullandığınızda, farklı tür kullanmanız durumunda sizi uyaracak ve birkaç başka şeyde yardımcı olacaktır. Yukarıdaki cevapta önerilen blog gönderisini okumanızı tavsiye ederim.
Nerxis

Bu hesaplama açısından daha hızlı mı?
Bryce Wayne

18

Dinamik diller bu şekilde çalışır. Her zaman iyi bir şey değildir, özellikle de dokümantasyon zayıfsa - kimse kötü bir şekilde belgelenmiş bir python çerçevesi kullanmaya çalıştı mı? Bazen kaynağı okumaya geri dönmeniz gerekir.

Ördek yazmayla ilgili sorunları önlemek için bazı stratejiler şunlardır:

  • sorun etki alanınız için bir dil oluşturun
  • bu, şeyleri doğru bir şekilde adlandırmanıza yardımcı olur
  • etki alanı dilinizdeki kavramları temsil etmek için türleri kullanın
  • etki alanı dili sözlüğünü kullanan ad işlevi parametreleri

Ayrıca en önemli noktalardan biri:

  • verileri olabildiğince yerel tutun!

Sadece birkaç iyi tanımlanmış ve belgelenmiş tür aktarılmalıdır. Koda bakarak başka her şey açık olmalıdır: Kodun çevresine bakarak anlayamayacağınız, çok uzaklardan gelen garip parametre türlerine sahip olmayın ...

İlgili (ve ayrıca docstrings ile ilgili), python adında bir teknik var doctests. Yöntemlerinizin nasıl kullanılmasının beklendiğini belgelemek ve aynı zamanda güzel bir birim testi kapsamı elde etmek için bunu kullanın!


1
Hantal dokümantasyon, yukarıdaki cevapta belirtilen felsefenin iyi bir temsili örneğidir.
Jerry Ajay

7

Bir kurs kursuna katıldım, ders vardı ki, bize tasarım tarifi öğretildi.

Docstring formatının altında preety'yi yararlı buldum.

def alanı (taban, yükseklik):
    '' '(sayı, sayı) -> sayı # ** TypeContract **
    # ** Açıklama ** taban ölçüleriyle bir tringin alanını döndür
    ve yükseklik

    >>> alan (10,5) # ** Örnek **
    25.0
    >> alan (2.5,3)
    3.75
    '' '
    dönüş (taban * yükseklik) / 2 

Bence dokümanlar bu şekilde yazılırsa, geliştiricilere çok yardımcı olabilir.

Video bağlantısı [ Videoyu izleyin] : https://www.youtube.com/watch?v=QAPg6Vb_LgI


5

Evet, sınıflarınızı ve işlevlerinizi diğer programcılar için daha kolay hale getirmek için docstrings kullanmalısınız:

Daha fazla: http://www.python.org/dev/peps/pep-0257/#what-is-a-docstring

Bazı editörler yazarken docstrings görmenize izin verir, bu yüzden işi gerçekten kolaylaştırır.


+1: belgeleyin, tek mantıklı yol bu ve statik olarak yazılan diller için de durum bu. İade türleri, tüm resmin önemsiz bir bölümüdür.
detly

Türlerimi seviyorum çok teşekkür ederim. Belgeler + türler = cennet
masm64

2

Evet öyle.

Python'da bir işlevin her zaman aynı türden bir değişken döndürmesi gerekmez (ancak işlevleriniz her zaman aynı türü döndürürse kodunuz daha okunaklı olacaktır). Bu, işlev için tek bir dönüş türü belirtemeyeceğiniz anlamına gelir.

Aynı şekilde, parametrelerin de her zaman aynı türde olması gerekmez.


1

Örneğin: bir dokümantasyon dizesinde, bir işlevin formun her bir demetiyle (düğüm_kimliği, düğüm_adı, çalışma süresi_dakika) bir demet listesi döndürdüğünü ve öğelerin sırasıyla bir dizge, dizge ve tamsayı olduğunu kısaca nasıl açıklayabilirim?

Um ... Bunun "kısa" bir açıklaması yok. Karmaşık. Karmaşık olacak şekilde tasarladınız. Ve docstring'de karmaşık belgeler gerektirir.

Maalesef karmaşıklık - iyi - karmaşık.


3
TAMAM. Konu dışı (çeşit): ama o zaman daha temiz bir tasarım ne olurdu? Sınıflar?
Rabarberski

@Rabarberski: Mutlaka değil. Karmaşıklık burada kaçınılmaz görünüyor. Kısa ve öz her zaman ulaşılabilir ve hatta arzu edilen bir şey değildir.
S.Lott

1
Bu tür şeyleri belgelemenin açık bir yolu, Java jeneriklerine benzer bir şey kullanmaktır, örneğin: list <tuple <int, str, int >>. Ama bu Python yolu değil, iyi ya da kötü.
skyler


0

Belgeler (ve genel olarak belgeler). Python 3, PEP 3107'de açıklandığı gibi (isteğe bağlı) işlev açıklamaları sunar (ancak belge dizilerini dışarıda bırakmayın)

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.