Python 3'te generator.next () görülüyor mu?


247

Bir seri üreten bir jeneratör var, örneğin:

def triangle_nums():
    '''Generates a series of triangle numbers'''
    tn = 0
    counter = 1
    while True:
        tn += counter
        yield tn
        counter += + 1

Python 2'de aşağıdaki aramaları yapabilirim:

g = triangle_nums()  # get the generator
g.next()             # get the next value

Ancak aynı iki satır kod yürütmek Python 3 aşağıdaki hatayı alıyorum:

AttributeError: 'generator' object has no attribute 'next'

ancak, döngü yineleyici sözdizimi Python 3'te çalışır

for n in triangle_nums():
    if not exit_cond:
       do_something()...

Python 3'teki davranış farklılıklarını açıklayan hiçbir şey bulamadım.

Yanıtlar:


406

g.next()olarak yeniden adlandırıldı g.__next__(). Bunun nedeni tutarlılıktır: __init__()ve gibi __del__()tüm özel yöntemlerin çift ​​alt çizgileri vardır (veya geçerli yerel dilde "dunder") ve.next() bu kuralın birkaç istisnasından biridir. Bu Python 3.0'da düzeltildi. [*]

Ama aramak yerine g.__next__(), kullanın next(g).

[*] Bu düzeltmeyi yapan başka özel özellikler de var; func_nameŞimdi, __name__, vb


Python 2'nin neden bu yöntemler için dunder konvansiyonundan kaçındığı hakkında herhangi bir fikir?
Rick,

Muhtemelen bu sadece bir gözetim.
Lennart Regebro

Sınıflarda __ str __ üzerine yazdığınızda ne olur? Str (obj) veya __str __ (obj) değiştirir mi?
NoName

@NoName diye bir şey yok __str__(obj), bu yüzden soruyu gerçekten anlamıyorum.
Lennart Regebro

1
@NameName Evet, biliyorsun.
Lennart Regebro

144

Deneyin:

next(g)

Bu sözdizimi söz konusu olduğunda 2 ile 3 arasındaki sözdizimindeki farklılıkları gösteren bu düzgün tabloya göz atın .


1
@MaikuMori Bağlantıyı düzelttim (akran revizyonu bekleniyor ) ( diveintopython3.org sitesi çalışmıyor gibi görünüyor. Ayna sitesi diveintopython3.ep.io hala yaşıyor)
gecco

1
Bağlantı tekrar düzeltildi. python3porting.com/differences.html daha eksiksiz, btw.
Lennart Regebro

Bir yöntemden bir işleve geçiş için herhangi bir gerekçe var mı, ötesinde g.next()olmalı g.__next__()ve işlevselliği ile bir dunder yöntemi olmayan bir şeye ihtiyacımız var g.next()mı?
TC Proctor

11

Kodunuzun Python2 ve Python3 altında çalışması gerekiyorsa, 2to3 altı kitaplığı şu şekilde kullanın:

import six

six.next(g)  # on PY2K: 'g.next()' and onPY3K: 'next(g)'

18
2.6'dan önceki Python sürümlerini desteklemeniz gerekmedikçe buna çok fazla ihtiyaç yoktur. Python 2.6 ve 2.7 nextyerleşik işleve sahiptir.
Mark Dickinson
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.