กำลังรีเฟรชโมดูลที่อิมพอร์ตในกล่องเครื่องมือ ArcGIS Python?


15

เมื่อใช้กล่องเครื่องมือหลาม (.pyt) ใน ArcMap โดยทั่วไปแล้วฉันจะทำตามรูปแบบที่ไฟล์. pyt นั้นเป็นตัวหุ้มในการรวบรวมอาร์กิวเมนต์อินพุตและกำหนดเครื่องมือเอง รหัสสนับสนุนจะถูกเก็บไว้ในโมดูลที่ทดสอบแยกหน่วยได้

ตัวอย่าง:

import supporting_module

class MyTool(object):

    ...

    def execute(self, parameters, messages):
        """The source code of the tool."""
        some_input = parameters[0].valueAsText
        some_output = parameters[1].valueAsText

        supporting_module.do_something(some_input, some_output)
        arcpy.SetParameter(2, some_output)

มันใช้งานได้ดีมาก แต่ฉันพบเจอปัญหาที่น่าผิดหวังอย่างหนึ่งระหว่างการพัฒนา คลิกขวา -> รีเฟรชที่. pyt ใน ArcMap รีเฟรชโค้ดของไฟล์. pyt เท่านั้น มันไม่รีเฟรชโมดูลที่นำเข้าดังนั้นฉันต้องปิดและเปิด ArcMap ใหม่ทุกครั้งที่ฉันเปลี่ยนบางสิ่งที่นั่น โชคดีที่ฉันกำลังทดสอบโค้ดอย่างอิสระฉันไม่ต้องทำแบบนี้เลย แต่มันก็ยังเป็นปัญหาที่สำคัญ มีวิธีใดบ้างไหม? ค่อนข้างเกี่ยวข้อง - มีวิธีใดที่จะรีเฟรชคอนโซล Python อย่างสมบูรณ์ (ฉันมีแพ็คเกจไซต์ที่กำหนดเองที่ฉันต้องปิด / เปิด ArcMap อีกครั้งเพื่อดึงการเปลี่ยนแปลงจากเช่นกัน)

ฉันใช้ ArcMap 10.2.1

คำตอบ:


14

ฉันพบความเป็นไปได้นี้/programming/1517038/python-refresh-reload

หนึ่ง caveat คือถ้าคุณมีตัวแปรใด ๆ ที่กำหนดให้กับโมดูลพวกเขาจะต้องได้รับมอบหมายอีกครั้ง

แต่ตามที่คุณเขียนไว้ด้านบนคุณสามารถทำได้:

import supporting_module
def execute()
  reload(supporting_module)
  ...

วิธีนี้ทุกครั้งที่คุณเรียกใช้เครื่องมือคุณจะมั่นใจได้ว่าจะมีโมดูลที่อัปเดตแล้ว เมื่อการพัฒนาเสร็จสิ้นสามารถดำเนินการได้


1
มีประโยชน์อย่างยิ่งและนี่จะช่วยแก้ปัญหาตัวอย่างง่ายๆที่ฉันโพสต์ อย่างไรก็ตามหากสนับสนุน _module ยังนำเข้าโมดูลตัวช่วยอื่น ๆ พวกเขาจะต้องเรียกด้วยการโหลดซ้ำเช่นกัน ฉันคิดว่านี่เป็นสิ่งที่ดีที่สุดที่เราจะได้รับเนื่องจากเหมาะสมกับวิธีที่ Python โหลดโมดูล - ฉันจะทำเครื่องหมายว่าคุณเป็นคำตอบหากสิ่งที่มีประสิทธิภาพมากกว่านั้นไม่มาในวันถัดไป
Josh Werts

มีประโยชน์มาก ฉันพบว่ามันเพียงพอที่จะเรียกใช้reload()หลังจากนำเข้าโมดูลสนับสนุนที่ด้านบนของไฟล์ PYT ของกล่องเครื่องมือ ดังนั้นหากกล่องเครื่องมือมีเครื่องมือหลายอย่างฉันไม่จำเป็นต้องทำการรีโหลดซ้ำในexecute()ฟังก์ชั่นของเครื่องมือแต่ละตัว
Mike Finch

ฉันไม่เข้าใจจริงๆว่าตัวแก้ปัญหานี้แก้ปัญหาอย่างไร ฉันมีเครื่องมือของฉันเก็บไว้ในไฟล์ .pyและผมนำพวกเขาใช้from pyfile import Toolเพิ่มผลตอบแทนreload(tool) typeError: reload() argument must be moduleความคิดใด ๆ
Ratnanil

2
ฉันพบวิธีแก้ปัญหา! นำเข้าไฟล์ py เป็นโมดูลก่อนโหลดแล้วนำเข้าชั้นเรียนภายในโมดูล ดู: stackoverflow.com/a/6946467/4139249
Ratnanil

5

นี่คือวิธีที่แตกต่างและแข็งแกร่งกว่าที่ฉันแนะนำไว้ก่อนหน้านี้

ฉันไม่ได้ใช้โมดูลนี้ด้วยตัวเอง แต่ฉันคิดว่ามันจะช่วยแก้ปัญหาของคุณได้:

Python Module Reloader

ไลบรารีนี้ใช้ reloader โมดูลอ้างอิงตามสำหรับ Python ซึ่งแตกต่างจากฟังก์ชั่น relin () ฟังก์ชั่นโหลดใหม่นี้จะโหลดโมดูลที่ร้องขอและโมดูลอื่น ๆ ทั้งหมดที่ขึ้นอยู่กับโมดูลนั้น

รับตัวอย่างก่อนหน้านี้ควรโหลดการพึ่งพาทั้งหมดด้วยสายเดียว:

import reloader
reloader.enable()

import supporting_module

def execute()
  reloader.reload(supporting_module)
  ...

นี่เป็นครั้งแรกที่ฉันสังเกตเห็นโมดูลนี้ดังนั้นหากคุณนำไปใช้ในเครื่องมือของคุณให้แสดงความคิดเห็นกลับมาว่ามันทำงานได้ดีแค่ไหนสำหรับคุณ


หาดี! สิ่งนี้จะทำงานหากมีการเพิ่มอย่างแน่นอนตามที่คุณแสดง ฉันต้องคลิกขวา -> รีเฟรชในกล่องเครื่องมือหากไฟล์. pyt เปลี่ยนไป โมดูลที่สนับสนุนและโมดูลย่อยกำลังโหลดซ้ำได้สำเร็จ แต่ข้อแม้หนึ่งข้อ - ฉันได้รับข้อยกเว้นที่ไม่สามารถอธิบายได้สองสามครั้งในบางครั้งและความผิดพลาดของ ArcMap (แม้ว่าการล่มของ ArcMap จะไม่ผิดปกติ แต่น่าเสียดาย) หมายเหตุ - ฉันเพิ่งทดสอบสิ่งนี้กับโมดูลที่สนับสนุนและโมดูลย่อยที่ขึ้นต่อกันหนึ่งโมดูล อาจรายงานกลับมาเกี่ยวกับความมั่นคงในอนาคต
Josh Werts

1
สุดยอดขอบคุณสำหรับการรายงานกลับ ใช่ตอนขับ ArcMap บางครั้งฉันรู้สึกเหมือน Crash Test Dummy
cndnflyr

น่าเสียดายที่ฉันพบปัญหาเสถียรภาพมากเกินไปกับตัวโหลดนี้ดังนั้นฉันจึงเปลี่ยนคำตอบที่เลือกไปเป็นฟังก์ชั่นการรีโหลดในตัว () เดิม บางครั้งง่ายกว่าดีกว่า!
Josh Werts
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.