2013-07-28 7 views
6

Załóżmy, że masz ciąg zawierający ścieżkę do skryptu w języku Python i chcesz załadować i wykonać ten skrypt w przejrzysty sposób (aby nie było fundamentalnych różnic dla skryptu wewnętrznego w porównaniu do uruchamiania bezpośrednio przez "ścieżkę pythona"). A następnie uzyskać wynikowy globalny dykt. Pomyślałem, że runpy.run_path() robi to, ale są dwa problemy. Jeśli ścieżka zawiera jakiś znak Unicode, to nie działa (zobacz http://bugs.python.org/issue17588). A co najważniejsze, biorąc pod uwagę globalny dyktat jest tylko kopią oryginalnego, ponieważ ten oryginalny jest czyszczony, gdy tymczasowy obiekt modułu jest zbierany śmieci. Tak więc obiekt funkcji spowodował uszkodzenie __globals__ dict (patrz http://bugs.python.org/issue18331).Jak uruchomić skrypt Python z innego skryptu i uzyskać wynikowy globalny dict?

Czy masz pomysły na uruchomienie wewnętrznego skryptu?

Aktualizacja: Zobacz moje bieżące podejście - http://bpaste.net/show/RzAbQxLNXiJsXYm2fplz/. Jakieś sugestie? Ulepszenia? Na przykład o szczegółach, które mogą być różne od punktu widzenia uruchamianego skryptu. Wiem o problemie z realoadingiem __main__.

+3

przepisać „wewnętrzny” scenariusz się do użytku jako moduł ... – l4mpi

+0

[execfile()] (http://docs.python.org /2/library/functions.html?highlight=execfile#execfile). – martineau

+0

@ l4mpi: Ścieżka i skrypt wewnętrzny nie są naprawione. – user87690

Odpowiedz

1

Importowanie moduł wykonuje kod na najwyższym poziomie, a nazw tego modułu jest „globalny” importowane jako nazwa modułu

[email protected]:~$cat test.py 
def func(): 
    pass 

myname = "michael caine" 

print "hello, %s" % myname 
[email protected]:~$python 
Python 2.7.5 (default, Jul 12 2013, 18:42:21) 
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import test 
hello, michael caine 
>>> dir(test) 
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'func', 'myname'] 
>>> 

jeśli kod chcesz być prowadzone jest na najwyższym poziomie pliku, po prostu importowanie modułu wykona kod i daje dostęp do "globalnej" przestrzeni nazw w jednym wygodnym pakiecie. Jeśli kod chcesz uruchomić nie jest na najwyższym poziomie (na przykład, jeśli jest to w main() funkcji, tylko zostanie wzbudzony ze wspólnym if __name__=="__main__" podstęp), można wywołać tej funkcji siebie:

[email protected]:~$cat test.py 

def main(): 
    print "hello there!" 

if __name__=="__main__": 
    main() 
[email protected]:~$python 
Python 2.7.5 (default, Jul 12 2013, 18:42:21) 
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import test 
>>> test.main() 
hello there! 
>>> 

Oczywiście , możliwe, że plik, który chcesz zaimportować, nie znajduje się w sys.path, więc nie można go po prostu załadować z import. Uproszczony roztwór może być manipulowanie sys.path, ale How to import a module given the full path? opisano lepszych rozwiązań wykorzystujących imp.load_source()

+0

Działa to tylko wtedy, gdy logika najwyższego poziomu skryptu znajduje się w funkcji wywoływanej z tablicy 'if __name__ ==" __main __ "'. Chociaż jest to dobry projekt, możesz nie móc polegać na tym, że jest używany przez inny kod. – Blckknght

+0

To prawda, wywołanie 'main()' będzie przydatne tylko wtedy, gdy kod, który chcesz uruchomić, znajduje się wewnątrz funkcji o nazwie 'main()'. Jeśli znajduje się w innej funkcji, musisz wywołać tę funkcję. Jeśli funkcja przyjmuje argumenty, musisz je również podać. –

+0

Mam ścieżkę skryptu, nie może być w sys.path do załadowania. Również to nie działa dla nazwy pliku Unicode, ponieważ istnieje błąd, więc nie możesz "zaimportować α". – user87690

Powiązane problemy