การโหลดโมดูลที่ให้ NameError: ไม่ได้กำหนดชื่อ 'reload'


162

ฉันกำลังพยายามโหลดโมดูลที่ฉันได้นำเข้าแล้วใน Python 3 ฉันรู้ว่าคุณจะต้องนำเข้าเพียงครั้งเดียวและดำเนินการimportคำสั่งอีกครั้งจะไม่ทำอะไรเลย

กำลังดำเนินการreload(foo)ให้ข้อผิดพลาดนี้:

Traceback (most recent call last):
    File "(stdin)", line 1, in (module)
    ...
NameError: name 'reload' is not defined

ข้อผิดพลาดหมายถึงอะไร

คำตอบ:


239

reload เป็น builtin ใน Python 2 แต่ไม่ใช่ใน Python 3 ดังนั้นคาดว่าจะเกิดข้อผิดพลาด

หากคุณต้องโหลดโมดูลใน Python 3 จริงๆคุณควรใช้:

  • importlib.reload สำหรับ Python 3.4 ขึ้นไป
  • imp.reloadสำหรับ Python 3.0 ถึง 3.3 (เลิกใช้แล้วตั้งแต่ Python 3.4 เพื่อประโยชน์importlib)

37
คำตอบนี้ทำให้ฟังดูไม่ดีที่จะโหลดโมดูลใน Python 3 ความคิดที่อยู่เบื้องหลังนี้คืออะไร
ABM

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

13
ฉันจะบอกว่ามันมักจะมีปัญหา แต่ไม่เสมอไป เพื่อให้แน่ใจว่าฉันคิดว่ากรณีการใช้งานที่ถูกต้องสำหรับการเขียนreloadสคริปต์นั้นหายากมากและผู้ที่ใช้งานศิลปะประเภทมืดนั้นไม่น่าที่จะอ่านความคิดเห็นนี้ อย่างไรก็ตามหากคุณกำลังพัฒนาโมดูลและใช้คอนโซล IPython เพื่อทดสอบการโต้ตอบนั้นreloadจะมีประโยชน์ในกระบวนการทำงานนั้น ในฐานะที่เป็น @Evan กล่าวแม้ว่าระวังผลข้างเคียงเวลานำเข้า โดยทั่วไปฉันจะบอกว่าเพื่อหลีกเลี่ยงการreloadไอเอ็นจีโมดูลของคนอื่น reloadไอเอ็นจีของคุณเองทำให้รู้สึกในช่วงเวลาการออกแบบ
ทิม D

6
ฉันใช้สมุดบันทึก Jupyter สำหรับงานของฉันและเพื่อให้เป็นระเบียบเรียบร้อยฉันใส่งานที่ควรมีการแก้ไขขั้นต่ำลงในแพ็คเกจที่นำเข้าได้ อย่างไรก็ตามบางครั้งสิ่งเหล่านั้นจำเป็นต้องมีการแก้ไขและการโหลดซ้ำเป็นสิ่งที่ถูกต้องอย่างแน่นอนเนื่องจากเคอร์เนลโน้ตบุ๊คของฉันถืออยู่ในการคำนวณหน่วยความจำที่ใช้เวลาทั้งหมดในการคำนวณ
Scott

การโหลดซ้ำมีความสำคัญต่อการพัฒนาห้องสมุดที่ต้องใช้เวลามากเช่นฟังก์ชั่นฐานข้อมูล อย่างไรก็ตามหนึ่งในปัญหาหลักที่คุณสามารถพบได้ในการโหลดโมดูลคือฟังก์ชั่นที่มีการตกแต่งจะมีแนวโน้มที่จะไม่โหลดอย่างถูกต้องดูที่นี่
Alexander McFarlane

82

สำหรับ> = Python3.4:

import importlib
importlib.reload(module)

สำหรับ <= Python3.3:

import imp
imp.reload(module)

สำหรับ Python2.x:

ใช้reload()ฟังก์ชั่นที่สร้างขึ้น

reload(module)

48
import imp
imp.reload(script4)

7
เลิกใช้ตั้งแต่ Python 3.4 - ใช้importlibแทน
Mark Amery

39

หากต้องการขยายคำตอบที่เขียนไว้ก่อนหน้านี้หากคุณต้องการโซลูชันเดียวซึ่งจะใช้ได้กับ Python เวอร์ชัน 2 และ 3 คุณสามารถใช้คำสั่งต่อไปนี้:

try:
    reload  # Python 2.7
except NameError:
    try:
        from importlib import reload  # Python 3.4+
    except ImportError:
        from imp import reload  # Python 3.0 - 3.3

12

ฉันขอแนะนำให้ใช้ข้อมูลโค้ดต่อไปนี้เพราะมันใช้ได้กับทุกเวอร์ชั่นของหลาม (ต้องการsix):

from six.moves import reload_module
reload_module(module)

2

สำหรับความเข้ากันได้ของ python2 และ python3 คุณสามารถใช้:

# Python 2 and 3
from imp import reload
reload(mymodule)

1
สามารถใช้งานได้ใน Python 3.7 (และรุ่นก่อนหน้า) แต่มีการระบุว่า @Alex Martelli เขียนไว้ด้านล่าง ใช้คำตอบของ Alleo 'จาก six.moves import reload_module'
Charles Plager

2

หากคุณไม่ต้องการใช้ libs ภายนอกวิธีแก้ปัญหาหนึ่งก็คือสร้างวิธีการโหลดซ้ำจาก python 2 สำหรับ python 3 ดังนี้ ใช้สิ่งนี้ที่ด้านบนของโมดูล (สมมติว่างูหลาม 3.4+)

import sys
if(sys.version_info.major>=3):
    def reload(MODULE):        
        import importlib
        importlib.reload(MODULE)

การโหลด BTW เป็นสิ่งจำเป็นอย่างยิ่งหากคุณใช้ไฟล์ไพ ธ อนเป็นไฟล์ปรับแต่งและต้องการหลีกเลี่ยงการรีสตาร์ทแอพพลิเคชั่น .....

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