return
Bir jeneratörde bir kez kullanabilirsiniz ; hiçbir şey üretmeden yinelemeyi durdurur ve böylece işlevin kapsam dışında kalmasına izin vermek için açık bir alternatif sağlar. Bu yüzden yield
işlevi bir jeneratöre dönüştürmek için kullanın , ancak return
herhangi bir şey üretmeden önce jeneratörü sonlandırmak için ondan önce gelin.
>>> def f():
... return
... yield
...
>>> list(f())
[]
Sahip olduğunuzdan çok daha iyi olduğundan emin değilim - sadece işlemsiz bir if
ifadeyi işlemsiz bir yield
ifadeyle değiştirir. Ama daha deyimsel. Sadece kullanmanın yield
işe yaramadığını unutmayın.
>>> def f():
... yield
...
>>> list(f())
[None]
Neden sadece kullanmıyorsun iter(())
?
Bu soru özellikle boş bir jeneratör işlevini soruyor . Bu nedenle, genel olarak boş bir yineleyici oluşturmanın en iyi yolu hakkında bir soru olmaktan ziyade, Python'un sözdiziminin iç tutarlılığıyla ilgili bir soru olarak kabul ediyorum.
Soru aslında boş bir yineleyici oluşturmanın en iyi yolu ile ilgiliyse , iter(())
bunun yerine kullanmak konusunda Zectbumo ile aynı fikirde olabilirsiniz . Ancak, bunun iter(())
bir işlev döndürmediğini gözlemlemek önemlidir ! Doğrudan boş bir yinelenebilir döndürür. Sıradan bir jeneratör işlevi gibi, her çağrıldığında bir yinelenebilir döndüren bir çağrılabilir bekleyen bir API ile çalıştığınızı varsayalım . Bunun gibi bir şey yapmanız gerekecek:
def empty():
return iter(())
( Bu cevabın ilk doğru versiyonunu vermek için kredi Unutbu'ya gitmelidir .)
Şimdi, yukarıdakileri daha net bulabilirsiniz, ancak daha az net olacağı durumları hayal edebiliyorum. Oluşturucu işlev tanımlarının uzun bir listesinin bu örneğini düşünün:
def zeros():
while True:
yield 0
def ones():
while True:
yield 1
...
Bu uzun listenin sonunda, içinde a olan bir şey görmeyi tercih ederim, şöyle yield
:
def empty():
return
yield
veya Python 3.3 ve üstünde ( DSM tarafından önerildiği gibi ), bu:
def empty():
yield from ()
yield
Anahtar kelimenin varlığı , en kısa bakışta bunun sadece diğerleri gibi başka bir jeneratör işlevi olduğunu açıkça ortaya koymaktadır. iter(())
Sürümün aynı şeyi yaptığını görmek biraz daha zaman alıyor .
Bu ince bir fark, ancak dürüst olmak gerekirse, yield
temelli işlevlerin daha okunabilir ve sürdürülebilir olduğunu düşünüyorum .
Ayrıca , bu yaklaşımın neden tercih edildiğinin başka bir nedenini göstermek için kullanan user3840170'in bu harika cevabına da bakın dis
: derlendiğinde en az talimat verir.
if False: yield
ama yine de biraz bu modeli bilmeyen insanlar için kafa karıştırıcı