generator.next () ปรากฏใน Python 3 หรือไม่


247

ฉันมีเครื่องกำเนิดไฟฟ้าที่สร้างซีรีส์เช่น:

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

ใน Python 2 ฉันสามารถโทรออกได้ดังต่อไปนี้:

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

อย่างไรก็ตามใน Python 3 หากฉันรันโค้ดสองบรรทัดเดียวกันฉันจะได้รับข้อผิดพลาดดังต่อไปนี้:

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

แต่ไวยากรณ์วนซ้ำตัววนซ้ำทำงานใน Python 3

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

ฉันยังไม่พบอะไรเลยที่อธิบายความแตกต่างของพฤติกรรมนี้สำหรับ Python 3

คำตอบ:


406

g.next()g.__next__()ได้รับการเปลี่ยนชื่อเป็น เหตุผลสำหรับเรื่องนี้คือความมั่นคง: วิธีการพิเศษเช่น__init__()และ__del__()ทุกคนมีขีดล่างคู่ (หรือ "dunder" ในภาษาพื้นปัจจุบัน) และ.next()เป็นหนึ่งในข้อยกเว้นบางประการสำหรับกฎนั้น สิ่งนี้ได้รับการแก้ไขใน Python 3.0 [*]

แต่แทนที่จะเรียกใช้g.__next__()next(g)

[*] มีคุณสมบัติพิเศษอื่น ๆ ที่ได้รับการแก้ไขนี้; func_nameคือตอนนี้__name__, ฯลฯ


ความคิดใดที่ว่าทำไมไพ ธ อน 2 จึงหยุดการทำข้อตกลง dunder สำหรับวิธีการเหล่านี้ตั้งแต่แรก?
Rick สนับสนุนโมนิก้า

นั่นอาจเป็นเพียงการกำกับดูแล
Lennart Regebro

แล้วเมื่อคุณเขียนทับ __ str __ ในชั้นเรียนแล้วล่ะ มันเปลี่ยน str (obj) หรือ __str __ (obj) หรือไม่
NoName

@ ไม่มีชื่อไม่มีสิ่งเช่น__str__(obj)นั้นดังนั้นฉันไม่เข้าใจคำถามจริงๆ
Lennart Regebro

1
@ ไม่มีชื่อใช่คุณทำ
Lennart Regebro

144

ลอง:

next(g)

ลองดูตารางที่เรียบร้อยที่แสดงความแตกต่างของไวยากรณ์ระหว่าง 2 และ 3 เมื่อพูดถึงเรื่องนี้


1
@MaikuMori ฉันคงการเชื่อมโยง (รอให้เพียร์แก้ไข) (เว็บไซต์diveintopython3.orgดูเหมือนว่าจะลงเว็บไซต์กระจก. diveintopython3.ep.ioยังมีชีวิตอยู่)
gecco

1
แก้ไขลิงก์อีกครั้ง python3porting.com/differences.htmlเสร็จสมบูรณ์มากขึ้น btw
Lennart Regebro

มีเหตุผลสำหรับการเปลี่ยนจากวิธีการไปยังฟังก์ชั่นที่เกินg.next()ควรg.__next__()และเราจำเป็นต้องมีสิ่งที่ไม่ได้เป็นวิธีการ dunder กับการทำงานของg.next()?
TC Proctor

11

หากรหัสของคุณต้องทำงานภายใต้ Python2 และ Python3 ให้ใช้ไลบรารี 2to3 sixดังนี้:

import six

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

18
ไม่จำเป็นต้องทำสิ่งนี้มากนักเว้นแต่คุณจะต้องสนับสนุน Python เวอร์ชันก่อนหน้า 2.6 Python 2.6 และ 2.7 มีnextฟังก์ชันในตัว
Mark Dickinson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.