Apakah generator.next () terlihat di Python 3?


247

Saya memiliki generator yang menghasilkan serangkaian, misalnya:

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

Dengan Python 2 saya dapat melakukan panggilan berikut:

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

Namun dalam Python 3 jika saya menjalankan dua baris kode yang sama saya mendapatkan kesalahan berikut:

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

tetapi, sintaks loop iterator bekerja di Python 3

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

Saya belum dapat menemukan apa pun yang menjelaskan perbedaan perilaku untuk Python 3 ini.

Jawaban:


406

g.next()telah diubah namanya menjadi g.__next__(). Alasan untuk ini adalah konsistensi: metode khusus seperti __init__()dan __del__()semua memiliki menggarisbawahi ganda (atau "dunder" dalam bahasa sehari-hari saat ini), dan .next()merupakan salah satu dari sedikit pengecualian untuk aturan itu. Ini diperbaiki dalam Python 3.0. [*]

Tapi alih-alih menelepon g.__next__(), gunakan next(g).

[*] Ada atribut khusus lain yang mendapatkan perbaikan ini; func_name, sekarang __name__, dll.


ada ide mengapa python 2 menghindari konvensi dunder untuk metode ini?
— Rick mendukung Monica

Itu mungkin hanya kekhilafan.
— Lennart Regebro

Bagaimana dengan saat Anda menimpa __ str __ di kelas? Apakah itu mengubah str (obj) atau __str __ (obj)?
— NoName

@NoName Tidak ada yang namanya __str__(obj), jadi saya tidak begitu mengerti pertanyaannya.
— Lennart Regebro

1
@NoName Ya, Anda tahu.
— Lennart Regebro

144

Mencoba:

next(g)

Lihat tabel rapi ini yang menunjukkan perbedaan dalam sintaks antara 2 dan 3 ketika sampai pada ini.


1
@MaikuMori Saya memperbaiki tautannya (menunggu revisi rekan) (Situs diveintopython3.org tampaknya sedang down. Situs mirror diveintopython3.ep.io masih hidup)
— gecco

1
Memperbaiki tautan lagi. python3porting.com/differences.html lebih lengkap, btw.
— Lennart Regebro

Apakah ada pembenaran untuk beralih dari suatu metode ke suatu fungsi, di luar g.next()seharusnya benar-benar g.__next__(), dan kita perlu memiliki sesuatu yang bukan metode dunder dengan fungsi g.next()?
— TC Proctor

11

Jika kode Anda harus dijalankan di bawah Python2 dan Python3, gunakan pustaka 2to3 enam seperti ini:

import six

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

18
Tidak ada banyak kebutuhan untuk ini kecuali Anda perlu mendukung versi Python lebih awal dari 2.6. Python 2.6 dan 2.7 memiliki nextfungsi bawaan.
— Mark Dickinson
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.