Wygląda na to, że anulowali w Pythonie 3 najłatwiejszy sposób szybkiego załadowania skryptu poprzez usunięcie execfile()
Czy brakuje mi oczywistej alternatywy?
Wygląda na to, że anulowali w Pythonie 3 najłatwiejszy sposób szybkiego załadowania skryptu poprzez usunięcie execfile()
Czy brakuje mi oczywistej alternatywy?
reload
powraca, ponieważimp.reload
od 3.2.%run script_name
działa ze wszystkimi wersjami Pythona.imp
jestimportlib
(co należy zaimportować):importlib.reload(mod_name)
importuje i wykonujemod_name
.runfile()
ponieważ musiałem uruchomić skrypt w języku Python, który działa we własnej przestrzeni nazw (w przeciwieństwie do wywoływania przestrzeni nazw wywołujących ). Moja aplikacja: dodaj katalog wywoływanego skryptu do ścieżki systemowej (sys.path
) za pomocą__file__
atrybutu: jeśli używamyexecfile()
lub jego odpowiednika w Pythonie 3 (exec(open('file.py').read())
), dołączony skrypt jest uruchamiany w przestrzeni nazw wywołujących, a tym samym__file__
rozwiązuje się do nazwy pliku wywołującego .Odpowiedzi:
Zgodnie z dokumentacją zamiast
Posługiwać się
Widzieć:
źródło
close
tego uchwytu pliku. Kolejny powód, by nie lubić zmiany z Pythona 2.Po prostu powinieneś przeczytać plik i sam wykonać kod. Prąd 2to3 zastępuje
tak jak
(Wywołanie kompilacji nie jest absolutnie potrzebne, ale wiąże nazwę pliku z obiektem kodu, co ułatwia debugowanie).
Widzieć:
źródło
exec
w Python2 znajduje się instrukcja,exec(code)
działa, ponieważ pareny są po prostu ignorowane."somefile.py"
zawarty,inspect.getsourcefile(lambda _: None)
który nie działał bez kompilacji, ponieważinspect
moduł nie mógł ustalić, skąd pochodzi kod.open("somefile.py")
może być niepoprawny, jeślisomefile.py
używa kodowania znaków innego niżlocale.getpreferredencoding()
.tokenize.open()
można zamiast tego użyć.Chociaż
exec(open("filename").read())
jest często podawany jako alternatywa dlaexecfile("filename")
, brakuje ważnych szczegółów, które byłyexecfile
obsługiwane.Poniższa funkcja dla Python3.x jest tak bliska, jak mogłem mieć takie samo zachowanie, jak bezpośrednie uruchamianie pliku. To pasuje do biegania
python /path/to/somefile.py
.Uwagi:
__main__
, że niektóre skrypty zależą od tego, czy sprawdzają, czy ładują się jako moduł, czy nie, np.if __name__ == "__main__"
__file__
jest lepsze dla komunikatów wyjątków, a niektóre skrypty używają__file__
do uzyskania ścieżek innych plików względem nich.Pobiera opcjonalne argumenty globals i locals, modyfikując je w miejscu, tak jak to
execfile
robi - abyś mógł uzyskać dostęp do dowolnych zdefiniowanych zmiennych poprzez odczytywanie zmiennych po uruchomieniu.W przeciwieństwie python2 jest
execfile
to nie nie zmodyfikować obecną nazw domyślnie. W tym celu musisz jawnie przekazaćglobals()
&locals()
.źródło
Jak zasugerowano ostatnio na liście mailingowej python-dev , moduł Runpy może być realną alternatywą. Cytując z tej wiadomości:
Istnieją subtelne różnice w
execfile
:run_path
zawsze tworzy nową przestrzeń nazw. Wykonuje kod jako moduł, więc nie ma różnicy między globalnymi a lokalnymi (dlatego jest tylkoinit_globals
argument). Globały są zwracane.execfile
wykonywane w bieżącej przestrzeni nazw lub w podanej przestrzeni nazw. Semantykalocals
iglobals
, jeśli podano, była podobna do miejscowej i globalnej w definicji klasy.run_path
może nie tylko wykonywać pliki, ale także jajka i katalogi (szczegółowe informacje można znaleźć w jego dokumentacji).źródło
file_globals
? Pozwoliłoby to zaoszczędzić konieczności wpisywaniafile_globals['...']
dla każdej zmiennej.Ten jest lepszy, ponieważ pobiera globalne i lokalne od dzwoniącego:
źródło
execfile
. To działało nawet dla mnie, gdy korzystałem z pytań, w których inne rozwiązania zamieszczone powyżej zawiodły. Dzięki! :)Możesz napisać własną funkcję:
Jeśli naprawdę potrzebujesz ...
źródło
globals
ilocals
punkt do globalnej przestrzeni nazw fo modułu zawierającego definicjęexecfile()
zamiast globalnej i lokalnej przestrzeni nazw rozmówcy. Prawidłowe podejście polega na użyciuNone
jako wartości domyślnej i określeniu globalnych i lokalnych obiektów wywołujących za pomocą funkcji introspekcjiinspect
modułu.Jeśli skrypt, który chcesz załadować, znajduje się w tym samym katalogu, co uruchomiony, być może „import” wykona zadanie?
Jeśli potrzebujesz dynamicznie importować kod, warto przyjrzeć się wbudowanej funkcji __ import__ i imp modułu .
test.py:
Jeśli używasz języka Python 3.1 lub nowszego, powinieneś także zajrzeć na importlib .
źródło
importlib
dev.to/0xcrypto/dynamic-importing-stuff-in-python--1805Oto, co miałem (
file
jest już przypisany do ścieżki do pliku z kodem źródłowym w obu przykładach):Oto, co zastąpiłem:
Moja ulubiona część: druga wersja działa dobrze zarówno w Pythonie 2, jak i 3, co oznacza, że nie trzeba dodawać logiki zależnej od wersji.
źródło
Zauważ, że powyższy wzór nie powiedzie się, jeśli używasz deklaracji kodowania PEP-263, które nie są ascii ani utf-8. Musisz znaleźć kodowanie danych i zakodować je poprawnie przed przekazaniem go do exec ().
źródło
Ponadto, mimo że nie jest to czyste rozwiązanie w języku Python, jeśli używasz IPython (jak i tak prawdopodobnie powinieneś), możesz:
Co jest równie łatwe.
źródło
Jestem tu tylko nowicjuszem, więc może to szczęście, gdybym to znalazł:
Po próbie uruchomienia skryptu z wiersza interpretera >>> za pomocą polecenia
dla którego dostałem „NameError: nazwa„ plik wykonywalny ”nie jest zdefiniowana” Próbowałem bardzo prosty
działało dobrze :-)
Mam nadzieję, że to może być pomocne i dziękuję wszystkim za wspaniałe wskazówki, przykłady i wszystkie te mistrzowsko skomentowane fragmenty kodu, które są wielką inspiracją dla początkujących!
Używam Ubuntu 16.014 LTS x64. Python 3.5.2 (domyślnie, 17 listopada 2016, 17:05:23) [GCC 5.4.0 20160609] w systemie Linux
źródło
Dla mnie najczystszym podejściem jest użycie
importlib
i zaimportowanie pliku jako modułu według ścieżki:Przykład użycia
Zróbmy plik
foo.py
:Teraz wystarczy zaimportować i używać go jak zwykłego modułu:
Wolę tę technikę od bezpośrednich podejść, takich jak,
exec(open(...))
ponieważ nie zaśmieca ona twoich przestrzeni nazw lub niepotrzebnie z nimi nie zadziera$PATH
.źródło