W zeszłym tygodniu opublikowałem pytanie dotyczące dostosowywania klasy ToolValidator i otrzymałem kilka bardzo dobrych odpowiedzi. Pracując z proponowanymi rozwiązaniami, stworzyłem moduł niestandardowy, który wykonuje zapytania na bazie danych i będzie wywoływany zarówno przez klasę ToolValidator (w celu dostarczenia wartości dla list rozwijanych), jak i później w skrypcie geoprocessingu (aby uzyskać inne parametry oparte na elementach wybranych z list rozwijanych). Nie wydaje mi się jednak, aby mógł wywoływać moduł niestandardowy w klasie ToolValidator. Próbowałem dołączyć do ścieżki bez powodzenia. Gdy próbuję zastosować te zmiany w skrypcie, pojawia się błąd czasu wykonania: [Errno 9] Zły deskryptor pliku. Jeśli skomentuję linię importu, żadnych błędów.
sys.path.append('my_custom_module_directory')
import my_custom_module
Wielu z was może pyta, dlaczego nie zaimplementuję niestandardowego narzędzia za pomocą ArcObjects. Powodem jest to, że moi użytkownicy końcowi nie mają uprawnień niezbędnych do zarejestrowania ŻADNYCH bibliotek DLL na swoim komputerze.
AKTUALIZACJA: Zdarzyło mi się to w ArcGIS 10. Co ciekawe, początkowo dołączałem się do ścieżki wewnątrz funkcji initialiazeParameters klasy ToolValidator. Jeśli wykonam dołączenie poza (tj. Na górze) klasy ToolValidator, wszystko działa zgodnie z oczekiwaniami.
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()
AKTUALIZACJA 2: Myślę, że znalazłem prawdziwą przyczynę mojego problemu. W fragmentach kodu w tym poście dodałem coś, co wydaje się prawdziwymi ścieżkami (np. C: / Working / SomeFolder) do sys.path. W mojej rzeczywistej klasie ToolValidator budowałem ścieżkę względną, używając os.path.dirname(__file__)
+ „\ mój_specjalny_folder ...”. Spodziewałem się, os.path.dirname(__file__)
że zwróci ścieżkę do przybornika, ponieważ zawiera on klasę ToolValidator. Przekonałem się, że tak nie jest. O ile mogę stwierdzić, klasa ToolValidator nigdy nie jest faktycznie zapisywana do pliku .py, i spekuluję, że ten kod jest przekazywany do interpretera python w pamięci, więc __file__
jest bezużyteczny lub jakiś skrypt tymczasowy jest utrwalany, a następnie wykonywalny ( ścieżka_do_skryptu), ponownie renderowane__file__
nieprzydatny. Jestem pewien, że są też inne powody, dla których tęsknię.
Krótko mówiąc, jeśli użyję zakodowanej ścieżki, sys.append działa wszędzie, ścieżki względne nie działają tak dobrze w klasie ToolValidator.
źródło
Odpowiedzi:
Sposób, w jaki to robię, to po uruchomieniu ArcGIS lub ArcCatalog najpierw uruchom fałszywe narzędzie („Uruchom raz”), wywołując skrypt dummy.py. Po wykonaniu tej czynności możesz zaimportować skrypty pythonowe w walidatorze za pomocą sys.argv [0]. Wskaże to folder, w którym znajdował się pierwszy skrypt. Następnie możesz zaimportować potrzebny skrypt do klasy de Validator.
Skrypt dummy.py wywoływany przez narzędzie „Uruchom raz”:
Niestety, nie można poprawnie sformatować Pozdrawiam, Maarten Tromp
źródło
W końcu złamałem ten okropny błąd! Na przykład podczas próby zastosowania zmian w celu zaimportowania względnego modułu lub pakietu może zostać wyświetlony następujący błąd:
Opcja 1:
Tylko dla dewelopera dodaj pełną ścieżkę do modułu do PYTHONPATH . Przed wejściem w życie musisz ponownie uruchomić ArcMap / ArcCatalog. Użyj poniższego kodu, aby zaimportować moduł ze ścieżki względnej (do wdrożenia). Nie martw się, użytkownik końcowy nie potrzebuje żadnych dodatków do swojej zmiennej PYTHONPATH, zadziała!
Opcja 2:
Dodaj dodatkowy wiersz do poniższego kodu, aby dodać ścieżkę zakodowaną na stałe, na przykład: sys.path.append (r "c: \ temp \ test \ scripts")
Gdy jesteś gotowy do wdrożenia, masz katalog zewnętrzny, ale to nie ma znaczenia, wszystko powinno działać na komputerze użytkownika końcowego, ponieważ pierwszą dodaną ścieżką był katalog względny (naszym celem było po prostu ominąć okno dialogowe awarii).
Kod wspólny dla obu opcji:
Aktualizacja
Pożegnanie zła wycinanie i wklejanie! Zaktualizowałem przykładowy kod, aby klasa ToolValidator została zaimportowana z biblioteki. Wycinam i wklejam tylko raz, gdy parametry narzędzia są ustawione po raz pierwszy. Przechowuję ten fragment kodu w dokumentacji importowanego narzędzia ToolValidator.
W tym przykładzie nazwa katalogu źródłowego jest oparta na nazwie tbx. Takie podejście pozwala uniknąć kolizji, jeśli masz dwa zestawy narzędzi z różnymi katalogami źródłowymi. Standard, którego użyłem do nazewnictwa folderów źródłowych, jest następujący:
TOOLBOXNAME__anything.tbx -> TOOLBOXNAME.src
Dlaczego „__wszystko”? Ponieważ plików binarnych nie można scalić w naszym systemie DVCS, możemy przypisywać narzędzia do osób i nie martwić się o utratę zmian. Po sfinalizowaniu narzędzie jest wycinane i wklejane do matrycy.
Potrzebowałem również dostępu do plików w folderze źródłowym, aby wypełnić menu rozwijane, użyj tej metody, aby uzyskać ścieżkę do zestawu narzędzi z zaimportowanego modułu:
źródło
Umieszczenie importu na górze modułu sprawdzania poprawności, poza
ToolValidator
klasą, wydaje mi się działać dobrze - mam 10.0 SP2. Jednak nic nie robię z zaimportowanym modułem nigdzie indziejupdateParameters
.źródło
Udało mi się przenieść moją weryfikację do pliku py, importując go i wywołując z poziomu istniejącej weryfikacji narzędzi TBX. Kluczem było wywołanie importu wewnątrz konstruktora. Jeśli wywołałem go spoza klasy ToolValidator, import nie powiódł się. Oto, co miałem w zakładce sprawdzania poprawności TBX.
Moja logika sprawdzania poprawności istniała następnie w ExportParcelIntersected.ToolValidator (). Gdzie można to łatwiej utrzymać.
źródło