NameError: ชื่อสากล 'xrange' ไม่ได้ถูกกำหนดใน Python 3


299

ฉันได้รับข้อผิดพลาดเมื่อเรียกใช้โปรแกรมหลาม:

Traceback (most recent call last):
  File "C:\Program Files (x86)\Wing IDE 101 4.1\src\debug\tserver\_sandbox.py", line 110, in <module>
  File "C:\Program Files (x86)\Wing IDE 101 4.1\src\debug\tserver\_sandbox.py", line 27, in __init__
  File "C:\Program Files (x86)\Wing IDE 101 4.1\src\debug\tserver\class\inventory.py", line 17, in __init__
builtins.NameError: global name 'xrange' is not defined

เป็นเกมที่มาจากที่นี่

อะไรทำให้เกิดข้อผิดพลาดนี้

คำตอบ:


570

คุณกำลังพยายามรันฐานข้อมูล Python 2 ด้วย Python 3 xrange()ถูกเปลี่ยนชื่อเป็นrange()ใน Python 3

รันเกมด้วย Python 2 แทน อย่าพยายามที่จะพอร์ตจนกว่าคุณจะรู้ว่าคุณกำลังทำส่วนใหญ่จะมีปัญหามากขึ้นเกินกว่าเมื่อเทียบกับxrange()range()

สำหรับบันทึกสิ่งที่คุณเห็นไม่ใช่ข้อผิดพลาดทางไวยากรณ์ แต่เป็นข้อยกเว้นแบบรันไทม์แทน


หากคุณไม่ทราบว่าสิ่งที่คุณกำลังทำและมีความกระตือรือร้นในการทำหลาม 2 codebase เข้ากันได้กับงูหลาม 3 rangeคุณสามารถสะพานรหัสโดยการเพิ่มชื่อระดับโลกเพื่อโมดูลของคุณเป็นชื่อแทนสำหรับ (คำนึงถึงว่าคุณอาจต้องปรับปรุงการrange()ใช้งานใด ๆ ที่มีอยู่ในฐานข้อมูล Python 2 ด้วยlist(range(...))เพื่อให้แน่ใจว่าคุณยังคงได้รับวัตถุรายการใน Python 3):

try:
    # Python 2
    xrange
except NameError:
    # Python 3, xrange is now named range
    xrange = range

# Python 2 code that uses xrange(...) unchanged, and any
# range(...) replaced with list(range(...))

หรือแทนที่การใช้ทั้งหมดของxrange(...)ด้วยrange(...)ใน codebase แล้วใช้ shim ที่แตกต่างกันเพื่อให้ไวยากรณ์ Python 3 เข้ากันได้กับ Python 2:

try:
    # Python 2 forward compatibility
    range = xrange
except NameError:
    pass

# Python 2 code transformed from range(...) -> list(range(...)) and
# xrange(...) -> range(...).

หลังเป็นที่นิยมสำหรับ codebases ที่ต้องการที่จะมุ่งมั่นที่จะหลาม 3 เข้ากันได้เพียง แต่ในระยะยาวก็จะง่ายต่อการจากนั้นเพียงแค่ใช้งูหลาม 3 ไวยากรณ์เมื่อใดก็ตามที่เป็นไปได้


8
ขอบคุณที่สังเกตความแตกต่างระหว่างข้อผิดพลาดทางไวยากรณ์และข้อยกเว้นรันไทม์ เรียนรู้สิ่งใหม่!
Pithikos

17

เพิ่มxrange=rangeในรหัสของคุณ :) มันทำงานให้ฉัน


7
ดังที่กล่าวไว้ในคำตอบที่ยอมรับอย่าทำเช่นนั้นมีแนวโน้มว่าจะมีปัญหาอื่น ๆ เพียงเรียกใช้รหัสนั้นใน python 2
RobinFrcd

2
@ Frost Xu ... โปรดพิจารณา Robin Fourcade ความคิดเห็นของเขาและนำคำตอบของคุณออก มันเป็น IDE สำหรับผู้เริ่มต้นและคุณไม่ต้องการเริ่มต้นด้วยการดำน้ำลึกลงในการดีบักและเรียนรู้เกี่ยวกับการเปลี่ยนแปลงของ python 2/3 ค่อนข้างเอวของเวลาของคุณ
ZF007

10

ฉันแก้ไขปัญหาโดยเพิ่มข้อมูล
เพิ่มเติมนำเข้านี้

from past.builtins import xrange

1
-------------------------------------------------- ------------------------- ModuleNotFoundError Traceback (การโทรล่าสุดครั้งล่าสุด) <ipython-input-21-bcd3600b3604> ใน <module> () - -> 1 จาก past.builtins นำเข้า xrange 2 สำหรับ i ใน xrange (10): 3 print (i) ModuleNotFoundError: ไม่มีโมดูลชื่อ 'past'
rsc05

2

ใน python 2.x, xrangeใช้เพื่อส่งคืนตัวกำเนิดในขณะที่ช่วงถูกใช้เพื่อส่งคืนรายการ ใน python 3.x, xrangeถูกลบและrangeส่งคืนตัวกำเนิดเช่นเดียวกับxrangeใน python 2.x ดังนั้นใน python 3.x คุณต้องใช้ range แทน xrange



0

ฉันเห็นด้วยกับคำตอบสุดท้าย แต่มีวิธีอื่นในการแก้ปัญหานี้คุณสามารถดาวน์โหลดแพคเกจที่มีชื่อในอนาคตเช่น pip การติดตั้งในอนาคตและในการป้อนไฟล์. py ของคุณนี้ "จาก past.builtins import xrange" สำหรับสถานการณ์ที่มี xranges จำนวนมากในไฟล์ของคุณ


แพคเกจนี้จะใช้ในการรับฟีเจอร์ของเวอร์ชันที่ใหม่กว่าเป็นไพ ธ อนรุ่นเก่า ไม่ใช่วิธีอื่น ๆ
mcsim

อะไรpast.builtings.rangeไม่ถูกตั้งค่าเพียงเพื่อจะอ้างอิงถึงxrange rangeสิ่งนี้มีประโยชน์เมื่อสร้าง Python 2/3 polyglot codebase แต่ไม่เหมาะสำหรับโครงการที่มีอยู่ที่ออกแบบมาเพื่อใช้กับ Python 2 เท่านั้น
Martijn Pieters
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.