web-dev-qa-db-ja.com

Pythonでプリプロセッサディレクティブに相当する方法を教えてください。

Pythonで次のプリプロセッサディレクティブを実行する方法はありますか?

#if DEBUG

< do some code >

#else

< do some other code >

#endif
57
intrepion

__debug__は、コンパイラーが前処理する特別な値です。

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

__debug__は、コンパイラによって定数0または1に置き換えられ、オプティマイザーはif 0:ソースが解釈される前の行。

100
habnabit

私が書いたpython pypreprocessorと呼ばれるプリプロセッサは、まさにあなたが説明していることをします。

ソースとドキュメントはGitHubで入手可能

パッケージはPyPIを介してダウンロード/インストールすることもできます

以下は、あなたが説明していることを達成するための例です。

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

pypreprocessorは、オンザフライの前処理よりもはるかに多くのことができます。ユースケースの例をもっと見るには、Google Codeのプロジェクトをご覧ください。

更新:pypreprocessorの詳細

前処理を行う方法は簡単です。上記の例から、プリプロセッサはpypreprocessorモジュールで作成されたpypreprocessorオブジェクトをインポートします。プリプロセッサでparse()を呼び出すと、インポートされるファイルを自己消費し、すべてのプリプロセッサコードをコメントアウトする自分自身の一時コピーを生成します(プリプロセッサが無限ループで再帰的に自分自身を呼び出さないようにするため)。すべての未使用部分をコメント化します。

モジュールが例外をスローしたりクラッシュしたりした場合、エラートレースバックで行番号を保持するには、行を削除するのではなく、コメントアウトする必要があります。また、エラートレースバックを書き直して、クラッシュしたモジュールの適切なファイル名を反映するように報告しました。

次に、後処理されたコードを含む生成されたファイルがオンザフライで実行されます。

コードにインラインで大量のifステートメントを追加するだけでこのメソッドを使用する利点は、コードのコメント化された部分がコンパイル済みの.pycファイルから除外されるため、無駄なステートメントを評価する実行時間の無駄がなくなります。

欠点(およびモジュールを作成した私の元の理由)は、python 2xとpython 3xを同じファイルで実行できないためです。コードを実行する前に完全な構文チェックを実行し、プリプロセッサが:: sigh ::を実行する前にバージョン固有のコードを拒否します。私の元の目標は、同じコードで2xおよび3xコードを並行して開発できるようにすることでした実行対象に応じてバージョン固有のバイトコードを作成するファイル。

いずれにしても、プリプロセッサモジュールは、一般的なCスタイルの前処理機能を実装するのに非常に便利です。同様に、プリプロセッサは、必要に応じて後で使用するために、後処理されたコードをファイルに出力できます。

また、すべてのプリプロセッサディレクティブと除外された#ifdefのいずれかが削除されたバージョンを生成する場合は、parse()を呼び出す前にプリプロセッサコードにフラグを設定するだけです。これにより、バージョン固有のソースファイルから不要なコードを1ステップのプロセスで削除できます(コードをクロールし、ifステートメントを手動で削除します)。

33
Evan Plaice

この答えを嫌うのではないかと思う。 Pythonでそれを行う方法は

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

pythonはインタプリタであるため、適用する前処理ステップはなく、特別な構文を使用することに特別な利点はありません。

22
Charlie Martin

Pythonでプリプロセッサを使用できます。 binディレクトリのcpp(Cプリプロセッサ)を介してスクリプトを実行するだけです。しかし、私はこれをLuaで行っており、簡単な解釈の利点は、より複雑なコンパイルIMHOを上回っています。

10
Robert Gould

通常の言語構成を使用できます。

DEBUG = True
if DEBUG:
  # Define a function, a class or do some crazy stuff
  def f():
    return 23
else:
  def f():
    return 42
3
phihag

別の方法は、bashスクリプトを使用して、デバッグにのみ関連するコードの一部をコメント化することです。以下は、 '#DEBUG'ステートメントを含む行をコメント化するスクリプトの例です。また、これらのコメントマーカーを再度削除することもできます。

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
2
slierp
  • Pythonは、配列から要素を削除できない場合。
  • Cプリコンパイラは#!を処理しません。または必要に応じて#で始まるその他の行。
  • pypreprocessorはpython特定

代わりに、次のような一般的なm4を使用します。

ifelse(DEBUG,True,dnl`
  < do some code >
dnl,dnl`
  < do some other code >dnl
')

ifelse(
  M4_CPU,x86_64,`
    < do some code specific for M4_CPU >
',M4_CPU,arm,`
    < do some code specific for M4_CPU >
',M4_CPU,ppc64le,`
    < do some code specific for M4_CPU >
')

ifelse(
  M4_OS,windows,`
    < do some code specific for M4_OS >
  ',M4_OS,linux,`
    < do some code specific for M4_OS >
  ',M4_OS,Android,`
    < do some code specific for M4_OS >
')

m4 -D DEBUG = True -D M4_OS = Android -D M4_CPU = arm test.py.m4> test.py

0