Jak zrobić odpowiednik dyrektyw preprocesora w Pythonie?

Czy istnieje sposób na wykonanie następujących dyrektyw preprocesora w Pythonie?

#if DEBUG

< do some code >

#else

< do some other code >

#endif
Author: intrepion, 2009-01-27

6 answers

Istnieje __debug__, która jest specjalną wartością, którą kompilator preprocesuje.

if __debug__:
  print "If this prints, you're not running python -O."
else:
  print "If this prints, you are running python -O!"

__debug__ zostanie zastąpiona stałą 0 LUB 1 przez kompilator, a optymalizator usunie wszelkie linie if 0: przed zinterpretowaniem źródła.

 93
Author: habnabit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-27 03:25:06

Napisałem preprocesor Pythona o nazwie pypreprocessor, który robi dokładnie to, co opisujesz.

Źródło i dokumentacja są dostępne na Google Code .

Pakiet można również pobrać/zainstalować za pośrednictwem PYPI .

Oto przykład, aby osiągnąć to, co opisujesz.

from pypreprocessor import pypreprocessor

pypreprocessor.parse()

#define debug

#ifdef debug
print('The source is in debug mode')
#else
print('The source is not in debug mode')
#endif

Pypreprocesor jest zdolny do znacznie więcej niż tylko do wstępnego przetwarzania w locie. Aby zobaczyć więcej przykładów przypadków użycia, sprawdź projekt w Google Kod.

Aktualizacja: więcej informacji o pypreprocessor

Sposób, w jaki dokonuję wstępnego przetwarzania jest prosty. Z powyższego przykładu preprocesor importuje obiekt pypreprocessor, który został utworzony w module pypreprocessor. Kiedy wywołujesz parse () na preprocesorze, sam zużywa on plik, do którego został zaimportowany i generuje swoją tymczasową kopię, która komentuje cały kod preprocesora (aby uniknąć wywołania samego siebie rekurencyjnie w nieskończonej loop) i komentuje wszystkie niewykorzystane części.

Komentowanie linii jest, w przeciwieństwie do ich usuwania, konieczne do zachowania numerów linii na ścieżkach błędów, jeśli moduł wyrzuci wyjątek lub zawiesi się. I nawet posunąłem się tak daleko, aby przepisać błąd traceback, aby zgłosić poprawną nazwę pliku modułu, który się rozbił.

Następnie wygenerowany plik zawierający postprocesorowany kod jest wykonywany w locie.

Plusem stosowania tej metody ponad dodanie kilku poleceń if inline w kodzie jest, nie będzie czasu wykonania zmarnowanego na ocenianie bezużytecznych poleceń, ponieważ skomentowane fragmenty kodu zostaną wyłączone z kompilacji .pliki pyc.

Minusem (i moim pierwotnym powodem utworzenia modułu) jest to, że nie można uruchomić zarówno Pythona 2x, jak i Pythona 3x w tym samym pliku, ponieważ interpreter pythons uruchamia pełną kontrolę składni przed wykonaniem kodu i odrzuci dowolny kod specyficzny dla wersji przed wykonaniem kodu. preprocesor może uruchomić :: sigh::. Moim pierwotnym celem było stworzenie kodu 2x i 3x obok siebie w tym samym pliku, który utworzyłby kod bajtowy w zależności od tego, na czym jest uruchomiony.

Tak czy inaczej, moduł preprocesora jest nadal bardzo przydatny do implementacji powszechnych możliwości przetwarzania wstępnego w stylu C. Preprocesor jest również w stanie przesyłać postprocesor kodu do pliku w celu późniejszego użycia, jeśli chcesz.

Również, jeśli chcesz wygenerować wersja, w której usunięto wszystkie dyrektywy preprocesora, jak również wszystkie wykluczone #ifdefs, jest tak prosta, jak ustawienie flagi w kodzie preprocesora przed wywołaniem parse(). To sprawia, że usuwanie niechcianego kodu z pliku źródłowego konkretnej wersji jest procesem jednoetapowym (zamiast przeszukiwania kodu i ręcznego usuwania instrukcji if).

 29
Author: Evan Plaice,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-25 06:20:23

Podejrzewam, że znienawidzisz tę odpowiedź. Sposób w jaki to robisz w Pythonie to

# code here
if DEBUG:
   #debugging code goes here
else:
   # other code here.

Ponieważ python jest interpreterem, nie ma etapu wstępnego przetwarzania i nie ma szczególnej korzyści z posiadania specjalnej składni.

 23
Author: Charlie Martin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-27 01:14:24

Możesz użyć preprocesora w Pythonie. Wystarczy uruchomić skrypty przez cpp (C-preprocesor) w katalogu bin. Jednak zrobiłem to z Lua i korzyści płynące z łatwej interpretacji przewyższyły bardziej złożoną kompilację IMHO.

 10
Author: Robert Gould,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-27 01:16:14

Możesz po prostu użyć normalnych konstrukcji językowych:

DEBUG = True
if DEBUG:
  # Define a function, a class or do some crazy stuff
  def f():
    return 23
else:
  def f():
    return 42
 4
Author: phihag,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-27 01:14:28

Alternatywną metodą jest użycie skryptu bash do komentowania fragmentów kodu, które są istotne tylko dla debugowania. Poniżej znajduje się przykładowy skrypt, który komentuje wiersze, które zawierają instrukcję '# DEBUG'. Może również usunąć te znaczniki komentarzy ponownie.

if [ "$1" == "off" ]; then
  sed -e '/^#/! {/#DEBUG/ s/^/#/}' -i *.py
  echo "Debug mode to $1"
elif [ "$1" == "on" ]; then
  sed -e '/#DEBUG/ s/^#//' -i *.py
  echo "Debug mode to $1"
else
  echo "usage: $0 on | off"
fi
 1
Author: slierp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-07 06:47:17