私はこれは良いアイデアだと思いますが、ここではあなたのロジックの文字通りの実装ですありません。
awk -F= '
/^[^#]/ && NF > 1 && saw_def { print "not global:", $0; next }
NF > 1 { print "possibly global:", $0 }
{ saw_def = /def/ }
' file.py
これは4 pattern {action}
ペアのフィールドセパレータとして=
を使用するためにはawkに指示します:
- 行は非
#
で始まり、2番目のフィールド(したがって、=
)を持ち、saw_def
変数が設定されます。
行をグローバル割り当てとして出力します。おそらくグローバル割り当て
- (#1にマッチしない任意の行)として
印刷ライン:
セットsaw_def
"か否かを示すブール値のラインが他=
を有する
- 次のライン(ストップパターンマッチング)に移動DEF」ここの行に
が存在するテストを失敗する例です。
def function_name():
int a = 4
int b = 8
あなたが要求したロジックがa
がnであることに注意しますグローバルであり、b
はおそらくグローバルです。
これは良いはずです:
awk '
NF == 0 { next }
{
indent = match ($0, /[^ \t]/) - 1 # count of leading whitespace
has_assign = /^[^#]*=/
}
$1 == "def" && !in_def { in_def = indent; next }
indent > in_def && has_assign { print "not global:", $0; next }
indent <= in_def { in_def = 0 }
has_assign { print "possibly global:", $0 }
' file.py
これは、あなたが関数定義にいるときを追跡するために、言語の必須インデントを利用して、Pythonのコードを解析しようとします。5 pattern {action}
ペアは次のとおりです:
- ませフィールド(空白行):最初の
を設定する前に先頭のスペースとタブの数に
設定indent
:
は、次の行
- (他のラインと一致)にスキップ
ind_def
を使用して、現在のインデントレベルを追跡し、ためにマッチング停止:変数の代入(=
がどの#
前に存在している)
- 最初のフィールドは「DEF」であり、我々はすでに機能を追跡していないがあるかどうかに
has_assign
このライン
- 私たちは、関数内であることが十分にインデントしていると我々は割り当てがあります。
レポート
- インデントレベルが最後の関数以下である非グローバル変数の代入:
を私たちはしていませんよ、任意のより多くの機能私たちは、変数の代入を持っている(そしてnext
はまだトリガされていない)ゼロ
- に戻す機能のインデントレベルを設定します。
レポートおそらく、グローバル変数の代入
注、私はないんだけどawk
のすべてのバージョンが01を理解していることを確認してくださいですので、その場所にリテラルタブが必要な場合があります。これをコマンドラインでのCtrl + v,タブと入力することができます。
私はまだ自家製Pythonのパーサは良いアイデアだとは思いません。あなたが実際に有効な(そして既知の安全な)Pythonコードを解析しているのであれば、this similar questionは実際にはのロードのコードを返答しています。潜在的に安全でないコードやPythonのようなコードを扱っている場合や、使用しているシステムでPythonインタプリタが不足している場合、私の解決策はコードの素早い確認に役立つかもしれません。
質問をより具体的にする2つの例を追加しました。 – learnerX
Pythonのソースコードを解析するために、行指向のツールを使用すると、Pythonで書かれた良いPythonのソースコードアナライザがあると、誤って指示されているようです。 – tripleee
可能な複製https://stackoverflow.com/questions/33160744/detect-all-global-variables-within-a-python-function – tripleee