Saya telah memposting pertanyaan minggu lalu tentang mengkustomisasi kelas ToolValidator dan mendapat beberapa jawaban yang sangat bagus. Dalam bekerja dengan solusi yang diusulkan, saya telah membuat modul khusus yang melakukan query pada db, dan akan dipanggil oleh kelas ToolValidator (untuk memberikan nilai untuk daftar drop-down) dan kemudian dalam skrip geoproses (untuk mendapatkan lainnya parameter berdasarkan item yang dipilih dalam daftar drop-down). Namun, sepertinya saya tidak dapat benar-benar memanggil modul khusus di kelas ToolValidator. Saya telah mencoba untuk menambahkan jalan tanpa hasil. Ketika saya mencoba menerapkan perubahan ini pada skrip, saya mendapatkan kesalahan runtime: [Errno 9] deskriptor file buruk. Jika saya mengomentari jalur impor, tidak ada kesalahan.
sys.path.append('my_custom_module_directory')
import my_custom_module
Banyak dari Anda mungkin bertanya mengapa saya tidak mengimplementasikan alat khusus dengan ArcObjects. Alasannya adalah bahwa pengguna akhir saya tidak memiliki hak istimewa yang diperlukan untuk mendaftarkan dll dll di komputer mereka.
UPDATE: Ini terjadi pada saya di ArcGIS 10. Cukup menarik, saya awalnya menambahkan ke jalur di dalam fungsi initialiazeParameters dari kelas ToolValidator. Jika saya menambahkan di luar (yaitu, di atas) dari kelas ToolValidator, semuanya berfungsi seperti yang diharapkan.
sys.path.append('C:/Working/SomeFolder')
import somescript -------->THIS WORKS
class ToolValidator:
"""Class for validating a tool's parameter values and controlling
the behavior of the tool's dialog."""
def __init__(self):
"""Setup arcpy and the list of tool parameters."""
import arcpy
sys.path.append('C:/Working/SomeFolder')
import somescript -------> THIS DOESNT WORK
self.params = arcpy.GetParameterInfo()
UPDATE 2: Saya pikir saya menemukan penyebab sebenarnya dari masalah saya. Dalam cuplikan kode dalam posting ini, saya telah menambahkan apa yang tampak sebagai jalur nyata (mis. C: / Working / SomeFolder) ke sys.path. Di kelas ToolValidator saya yang sebenarnya, saya membuat jalur relatif menggunakan os.path.dirname(__file__)
+ "\ my_special_folder ...". Saya mengantisipasi itu os.path.dirname(__file__)
akan mengembalikan jalur toolbox, karena itu berisi kelas ToolValidator. Saya datang untuk menemukan ini bukan masalahnya. Sejauh yang saya tahu, kelas ToolValidator tidak pernah benar-benar ditulis ke file .py, dan saya berspekulasi bahwa kode ini diteruskan ke juru bahasa python dalam memori, jadi __file__
tidak berguna, atau skrip temp tetap ada dan kemudian execfile ( path_to_script) dipanggil, lagi rendering__file__
tak berguna. Saya yakin ada alasan lain saya juga hilang.
Singkatnya, jika saya menggunakan jalur hardcoded, sys.append berfungsi di mana saja, jalur relatif tidak bekerja dengan baik di kelas ToolValidator.
sumber
Jawaban:
Cara saya melakukan ini adalah, setelah memulai ArcGIS atau ArcCatalog, pertama jalankan alat dummy ("Jalankan ini sekali") memanggil skrip dummy.py. Setelah melakukan itu, Anda dapat mengimpor skrip python di validator dengan menggunakan sys.argv [0]. Ini akan menunjuk ke folder di mana skrip pertama berada. Setelah itu Anda dapat mengimpor skrip yang diperlukan di Kelas de Validator.
Skrip dummy.py dipanggil oleh alat "Jalankan ini sekali":
Maaf, format pemformatannya tidak benar, Maarten Tromp
sumber
Akhirnya memecahkan bug mengerikan ini! Misalnya ketika Anda mencoba menerapkan perubahan untuk mengimpor modul atau paket relatif, Anda mungkin melihat kesalahan berikut:
Opsi 1: Hanya
untuk pengembang, tambahkan path lengkap ke modul ke PYTHONPATH . Anda harus memulai ulang ArcMap / ArcCatalog sebelum diberlakukan. Gunakan kode di bawah ini untuk mengimpor modul dari jalur relatif (untuk penempatan). Jangan khawatir, pengguna akhir tidak perlu menambahkan variabel PYTHONPATH mereka, itu akan berhasil!
Opsi 2:
Tambahkan baris tambahan ke dalam kode di bawah ini untuk menambahkan jalur hard-coded, misalnya: sys.path.append (r "c: \ temp \ test \ scripts")
Ketika Anda siap untuk menggunakan, Anda memiliki direktori asing, tetapi tidak masalah, semua harus bekerja di komputer pengguna akhir karena jalur pertama yang Anda tambahkan adalah direktori relatif (tujuan kami adalah untuk hanya melewati dialog kegagalan).
Kode umum untuk kedua opsi:
Memperbarui
Perpisahan kejahatan memotong dan menempel! Saya memperbarui sampel kode sehingga kelas ToolValidator diimpor dari perpustakaan. Saya memotong dan menempel hanya sekali ketika parameter alat ditetapkan pertama kali. Saya menyimpan potongan kode ini di docstring ToolValidator yang sedang diimpor.
Dalam contoh ini, nama direktori sumber didasarkan pada nama tbx. Pendekatan ini menghindari tabrakan jika Anda memiliki dua kotak alat dengan direktori sumber yang berbeda. Standar yang saya gunakan untuk penamaan folder sumber adalah sebagai berikut:
TOOLBOXNAME__anything.tbx -> TOOLBOXNAME.src
Kenapa "__anything"? Karena file biner tidak dapat digabungkan dalam DVCS kami, kami dapat menetapkan alat untuk individu dan tidak khawatir kehilangan perubahan. Ketika alat selesai, itu dipotong dan ditempelkan ke master.
Saya juga perlu mengakses file di folder sumber untuk mengisi dropdown, gunakan metode ini untuk mendapatkan path ke kotak alat dari dalam modul yang diimpor:
sumber
Menempatkan impor di bagian atas modul validasi, di luar
ToolValidator
kelas tampaknya berfungsi dengan baik untuk saya - Saya menggunakan 10,0 SP2. Namun saya tidak melakukan apa pun dengan modul yang diimpor di mana pun kecuali diupdateParameters
.sumber
Saya dapat memindahkan validasi saya ke file py dengan mengimpornya dan memanggilnya dari dalam validasi alat TBX yang ada. Kuncinya adalah memanggil impor di dalam konstruktor. Jika saya memanggilnya dari luar kelas ToolValidator, impor gagal. Inilah yang saya miliki di dalam tab validasi TBX.
Logika validasi saya kemudian tinggal di ExportParcelIntersected.ToolValidator (). Di mana itu bisa dipertahankan lebih mudah.
sumber