هل generator.next() مرئي في python 3.0؟
-
21-08-2019 - |
سؤال
لدي مولد يقوم بإنشاء سلسلة، على سبيل المثال:
def triangleNums():
'''generate series of triangle numbers'''
tn = 0
counter = 1
while(True):
tn = tn + counter
yield tn
counter = counter + 1
في python 2.6 يمكنني إجراء المكالمات التالية:
g = triangleNums() # get the generator
g.next() # get next val
ولكن في الإصدار 3.0، إذا قمت بتنفيذ نفس السطرين من التعليمات البرمجية، فسأتلقى الخطأ التالي:
AttributeError: 'generator' object has no attribute 'next'
لكن بناء جملة مكرر الحلقة يعمل في الإصدار 3.0
for n in triangleNums():
if not exitCond:
doSomething...
لم أتمكن من العثور على أي شيء حتى الآن يفسر هذا الاختلاف في السلوك لـ 3.0.
المحلول
وتصحيح، تمت إعادة تسمية g.next()
إلى g.__next__()
. والسبب في ذلك هو الاتساق: طرق خاصة مثل __init__()
و__del__
جميعا سفلية مزدوجة (أو "dunder" في العامية الحالية)، و.next()
كان واحدا من عدد قليل من الاستثناءات لهذه القاعدة. تم إصلاح هذا في بايثون 3.0. [*]
ولكن بدلا من استدعاء g.__next__()
، كما يقول باولو، واستخدام next(g)
.
[*] وهناك سمات خاصة الأخرى التي حصلت على هذا الإصلاح. func_name
، والآن __name__
، وما إلى ذلك.
نصائح أخرى
يحاول:
next(g)
الدفع هذه الطاولة الأنيقة يوضح الاختلافات في بناء الجملة بين 2 و 3 عندما يتعلق الأمر بهذا.
إذا يجب تشغيل التعليمات البرمجية تحت Python2 وPython3، استخدم 2to3 ستة مكتبة مثل هذا :
import six
six.next(g) # on PY2K: 'g.next()' and onPY3K: 'next(g)'