30

static analysis tools for Pythonが存在しますが、コンパイル時のチェックは、Pythonが受け入れるrun-time binding philosophyとは正反対の傾向にあります。 可能静的解析ツールで標準のPythonインタプリタをラップして "use strict"のような制約を適用することはできますが、そのようなことは広く普及していません。"strict strict" Pythonコンパイラが必要ですか?

「厳密な使用」の動作を不要にしたり、特に望ましくないものにするPythonについて何かありますか?

また、普及しているにもかかわらず、Perlでは「厳密な使用」の動作が不要ですか?

注:「必要」とは、「実際に必要」を意味し、厳密には必要ではありません。明らかにあなたはすることができます "厳格な使用"せずにPerlを書くが、(私が見たものから)ほとんどのPerlのプログラマを行うそれを使用してください。

メモ:にはの「厳密な」使用制限が必要である必要はありません。通常のインタープリタでは無視される「厳格」に似た疑似プラグマを使用できます。私は言語レベルの機能を追加するつもりはありません。


更新:Perlで "strict"が何をしているのかを説明しています。 (公式ドキュメントへのリンクは、最初の段落である。)

「を使用し、厳格な」ディレクティブ本当に面白いです2つのみ3つの異なるコンポーネント、があります。

  • 使用厳密VARS:静的レキシカルスコープのチェックをあなたのプログラムでの変数の使用。 (Pythonでは、基本的にglobalスコープとlocalスコープしか存在しません)。多くのPython lintersはこのようなことをチェックしています。彼らが行うことができる唯一の静的分析であるため、あなたは簡単な字句スコープを使用していると想定し、シャットダウンするまでその意味で間違っていることを警告します。すなわち

    FOO = 12 
    foo += 3 
    

    あなたの名前空間に夢中になっているのであれば、これはタイプミスをチェックするのに役立ちます。

  • 厳密なリファレンスを使用:シンボリック名前空間の逆参照を防止します。 Pythonのもっとも近いアナログは、シンボリックバインドと識別子検索を行うためにlocals()globals()を使用しています。

  • strict subsを使用してください:Pythonでは実際のアナログはありません。それは、「Python的」コードの理想的なように思える

+0

perlでstrictが何をするのか、なぜ必要なのか説明すると少し助けになりますか?なぜ多くの人々はいつもそれを使用していますか?それがなければ何が起こるだろうか? – hasen

+0

"use strict"が実際に何をしているのかについては、私の答えを見てください。この記事には混乱があり、実際に何を意味するのかについてのコメントがあるようです。はいPerlのプログラマーは "厳密に"使用していますが、PerlをJava-yにすることはありません。 – mpeters

+0

もちろんpython 3は、 '非ローカル'宣言を使って複雑なことを(明確にする?) - http://www.python.org/dev/peps/pep-3104/ – popcnt

答えて

12

不要だと言うことができます。ありがとう。

これは本質的にそれです。静的解析ツールは、Pythonを補うだけの価値があるとは限りません。


編集

「私はPerlプログラマは、彼らがそれを必要とすると思いますなぜ我々は、関連して、それを必要としませんなぜにイントロスペクションするために私たちのために求めています。」

正確すでに与えた理由である理由。それが役に立たないので、私たちはそれを必要としません。明らかに、あなたはその答えが気に入らないが、それ以上のことは言わない。コンパイル時またはコンパイル前の時間チェックは単に役に立ちません。

しかし、もう一度質問をしてくれたので、私はあなたがすでに与えた答えについてさらに多くの証拠を提供します。

私はPythonを書くのと同じくらいJavaを書きます。 Javaの静的型チェックはロジックの問題を防ぎません。パフォーマンス要件を満たすことを容易にしません。ユースケースを満たすのに役立つものではありません。それは単体テストの量を減らさない。

静的型チェックでは、メソッドの間違った使用を発見しますが、これはPythonの場合と同じように素早く実行されます。 Pythonでは、実行されないためユニットテスト時にそれを見つけることができます。注:私は、間違った型テストがたくさんあると間違った型が見つかったと言っているわけではありません。私は、間違った型の問題が、アサーションをテストするのに十分遠くまで走っていない未処理の例外を通して見つけられると言っています。

Pythonistasが静的検査で時間を無駄にしない理由は簡単です。私たちはそれを必要としません。それは価値を提供しません。それは経済的利益がない分析のレベルです。実際の人々が実際のデータを持っている実際の問題を解決することはできません。

言語(問題のドメインまたはライブラリではありません)に関連する最も一般的なSO Pythonの質問を見てください。

Is there any difference between "foo is None" and "foo == None"?-==isです。静的なチェックはこれを助けることができません。また、Is there a difference between `==` and `is` in Python?

What does ** (double star) and * (star) do for parameters?-*xは、**xが辞書を与える。あなたがこれを知らないならば、あなたはそれらのタイプに不適切な何かをしようとするとすぐにあなたのプログラムは死にます。 "もしあなたのプログラムが何か"不適切なこと "をしなければどうでしょうか?"その後、あなたのプログラムは動作します。 '言っ途切れる。

How can I represent an 'Enum' in Python? - これは限定ドメイン型の嘆願です。クラスレベルの値を持つクラスは、ほとんどその仕事をします。 "誰かが割り当てを変更したらどうなる?"簡単に構築できます。 __set__を上書きして例外を発生させます。はい静的なチェックがこれを検出する可能性があります。いいえ、誰かが列挙定数と変数について混乱することは実際には起こりません。そうしたときには、実行時に見つけやすくなります。 "論理が決して実行されなければどうなる?"まあ、それは設計が貧弱で単体テストが不十分です。コンパイルエラーを投げたり、テストされたことのない間違ったロジックを入れたりすることは、テストされていないときに動的言語で起きることよりも優れていません。

Generator Expressions vs. List Comprehension - 静的検査はこの問題の解決に役立ちません。

Why does 1+++2 = 3? - 静的検査ではこれが検出されません。 Cの1 +++ 2は、すべてのコンパイラチェックにもかかわらず、完全に正当です。 PythonではC言語と同じではなく、合法的です。そしてちょうど混乱する。

List of lists changes reflected across sublists unexpectedly - これは完全に概念です。静的検査はこの問題の解決にも役立ちません。 Java同等のものもコンパイルされ、ひどく振る舞います。

+8

あなたの答えは、「ただ必要ではありません。私は多くのPythonコードが無事に書かれていることを理解しています。なぜ私たちはそれが必要でないのか、それともPerlのプログラマがなぜそれを必要としているのかを尋ねることを求めています。 – cdleary

+0

最後の節にZen of Pythonの短い説明があります( 'use strict'のような静的なコンパイル時のチェックがなぜPythonではうまくいかないのか)。名前空間は素晴らしいアイデアです。 – popcnt

+1

ここでも、 "use strict"は静的なコンパイル時のチェックではありません。 – mpeters

-2

use strictと同じ目的の多くを提供しています。

from __future__ import print_function 

と構文の意味を持っている他のさまざまな未来-の特徴:

+0

正確に何を意味するのか詳しく説明できますか? 「厳密な使用」は明確に定義されていますが、「Pythonic」は十分に文書化されておらず、やや主観的です。 "これを輸入する"というのは十分な説明ではない。 ;-) – cdleary

+0

bobinceが深く説明しているように、Pythonは1つの明確なやり方しか持たないように努めているので、PythonはPerlが許す多くの構造を許可しませんでしたが、 'use strict'は許されません。 –

11

Pythonはスクリプトの構文を変更することができる何かを持っています。 Pythonの構文は歴史的なPerlよりも厳しく、安定しており、より明確に定義されています。 'strict refs'と 'strict subs'がPythonに存在することは決してありませんでした。

「厳しいVARSは」主に偶発グローバル(Perlの観点からだけでなく、パッケージ変数)を作成からtypoed参照して逃したアウト「私のを停止することを意図しています。これは、裸の代入がデフォルトでローカル宣言になっていて、未割り当ての未割り当てのシンボルが例外になるため、Pythonでは発生しません。

(「グローバル」ステートメントで宣言せずに誤ってグローバルにライトスルーしようとすると、間違ったローカルまたはUnboundLocalErrorが発生することがあります)これはかなり公平に学習される傾向があります

構文に関係しない他の言語とライブラリの変更は、warningsシステムを使って処理されています。これは、ローカルでの宣言が必要な場合に役立ちます。

+0

私はこの回答がどこにあるのが好きです。 globals()[]やlocals()[]を使用するとstrict refsと似ていると思いましたが、私はstrict subsに同意します。タイプミスをチェックする必要があるように思えますが、どうして人がタイプミスをチェックするために静的分析ツールの全面に落ちていないのでしょうか? – cdleary

3

あなたがを示唆したように私はPerlで'use strict'よりプラグマのように考えてみましょう。それは、コンパイラの動作を変更します。

Perl言語の哲学は、Pythonの哲学は異なっています。のように、Perlであなた自身を繰り返し吊るすのに十分なロープ以上が与えられます。

Larry Wall氏は、言語学に大きいので、私たちはTIMTOWTDI(たとえばtim-toe-dee)のpythonの禅対原則と呼ばれるものはPerlから持っている:

There should be one-- and preferably only one --obvious way to do it.

あなたは非常に簡単にpylintとPyCheckerを使用することができますあなた自身のフレーバーであるuse strictをpython(またはperl -cw *scriptname*に類似しています)で作成します。しかし、言語設計の考え方が異なるため、実際にはこれが広く遭遇することはありません。

最初のポスターにあなたのコメントをもとに、あなたはPythonのimport thisに精通しています。そこには、なぜuse strict相当のものがPythonで表示されないのかを示す多くのものがあります。 Zen of Pythonで見つけたkoanについて瞑想している場合は、自分で啓発を見つけることができます。私はPerlの背景を持っていないが、私が知っているから、あなたのコードは、「より信頼性」であるために無効にする必要のpythonには機能がありませんので、その意味で、私は推測:)

+3

私は本当の説明を与えずに "これを輸入する"という答えを私には見られないと思っていました。識別子スコープをチェックするコンパイラがPythonのThesesに違反するのはどうでしょうか?ランタイム検索によって静的な字句解析がどのように役に立たなくなるのでしょうか?私たちは、哲学が異なっていることを知っています。 – cdleary

+0

f名前のない変数(perlやpythonなどのいずれでも)を発見したり、それらを最初に阻止したりする手助けをしないエディタがない場合、静的な字句解析には肯定的なメリットがあります。 pylintとPyCheckerはこのスペースを適切にカバーしているようですね。 – popcnt

+0

はい、私の質問は、この種の静的解析を自動的に呼び出すコンパイラが必要なのかどうかです。また、どのエディターを紹介していますか?確かに、どのエディタを使用していても、*変数名はすべて自動完成されません。 – cdleary

-3

あなたはそれが「Pythonが包含することが...になり、実行時バインディングの哲学 『かなり良い要約』特に望ましくない動作不要[と]」

を厳格を使用

5

Pythonには真のレキシカルスコープがないため、厳密なヴァールはあまり賢明ではありません。それは象徴的な参照AFAIKを持っていないので、厳密な参照を必要としません。それは裸語ではないので、厳密なヴァールの必要はありません。

正直言って、それは私が見逃す字句の範囲です。他の2人はPerlで疣贅を考えています。

+0

二重アンダーバー(obj .__ attr)を持つ属性は、あなたにレキシカルスコープとして数えられませんか? – popcnt

+2

アトリビュートはレキシカルスコープとほとんど関係ありません。 –

+0

どういう意味ですか? Pythonは明らかに(少なくとも2.1以​​降)レキシカルスコープを持っていますが、厳密な宣言を要求することとは関係がありません。あなたはこれによって何か他のものを参照していますか? – Brian

7

私は見ているコメントから「厳密に使う」ものとして混乱があると思います。コンパイル時の型チェック(Javaのように)は有効になりません。その意味で、PerlのprogammersはPythonのプログラマーと合意しています。これらのタイプのチェックの上にあるS.Lottは論理バグから保護していないので、書く必要がある単体テストの数を減らさないでください。また、ボンデージプログラミングの大ファンでもありません。

はここでやるんどのような「厳格な使用」のリストです:シンボリック参照を使用して

  1. は、実行時エラーです。これは、あなたが狂ったことから防ぐ(時にはのような便利なもの)宣言されていない変数を使用する

    $var = 'foo';

    $foo = 'bar';

    print $$var; # this would contain the contents of $foo unless run under strict

  2. は、実行時エラーである(これは、「あなたが使用する必要があることを意味します私の」、 『それを使用する前に、変数のスコープを宣言する『当社』または』ローカル。

  3. すべての裸の単語がコンパイル時のSYと考えられていますntaxエラー。 Barewordsは、シンボルやサブルーチンとして宣言されていない単語です。これは主に、歴史的に行われたものの、間違いであったと思われるものを禁止することです。

+0

"単体テストの数を減らすことはできません":単純なタイプミスをチェックするために単なるキャッチアンドリザウンのメッセージブロックを単体テストすることは、プログラマーの時間の私が書いたほとんどのpythonistをユニットテストで判断すると、これはまれな意見ではありません。 –

34

私はPythonプログラマーではありませんが、回答は「はい」と言います。

任意の名前の変数をいつでも作成できる動的言語は、「厳密な」プラグマを使用できます。

Strict vars(Perlで厳密にするためのオプションの1つである 'use strict'は一度にすべてを有効にします)では、すべての変数を使用する前に宣言する必要があります。これは、次のコードを意味します。

my $strict_is_good = 'foo'; 
$strict_iS_good .= 'COMPILE TIME FATAL ERROR'; 

コンパイル時に致命的なエラーが生成されます。

私は、コンパイル時にこのコードを拒否するのPythonを取得する方法を知らない:

strict_is_good = 'foo'; 
strict_iS_good += 'RUN TIME FATAL ERROR'; 

あなたはstrict_iS_goodが未定義であることを、実行時例外が発生します。しかし、コードが実行されるときだけ。テストスイートのカバレッジが100%でない場合は、このバグを簡単に配布できます。

私はこの動作(例えばPHP)を持っていない言語で作業はいつでも、私が神経質。私は完璧なタイピストではありません。シンプルですが、見つけるのは難しい、タイプミスを追跡するのは難しいかもしれ形で失敗するようにコードを引き起こす可能性があります。

これを繰り返して、YES Pythonはコンパイル時にチェックできるものについてコンパイル時チェックを有効にするために 'strict'プラグマを使用できます。私は追加する任意の他のチェックを考えることはできませんが、より良いPythonプログラマは、おそらくいくつかを考えることができます。

注:私はPerlのstict varsの実用的な効果に焦点を当て、いくつかの細部を覆しています。あなたが本当に知りたい場合は、すべての詳細はthe perldoc for strictを参照してください。

更新:いくつかのコメントへの応答

ジェイソン・ベイカー:pylintのような静的チェッカーが便利です。しかし、彼らはできることがあり、しばしばスキップされる余分なステップを表します。コンパイラへのいくつかの基本的なチェックを構築することで、これらのチェックが一貫して実行されることが保証されます。これらの小切手がプラグマによって制御可能である場合、小切手のコストに関連する異論がなくなる。

popcnt:私はPythonが実行時例外を生成することを知っています。私はそれだけで言った。私は可能な限りコンパイル時間のチェックを主張する。投稿を読み直してください。

mpeters:コードのコンピュータ分析ですべてのエラーを見つけることはできません。これは停止問題を解決することになります。さらに悪いことに、代入を誤ると、コンパイラはの意思をと知り、あなたの意図と目的が異なる場所を見つける必要があります。これは明らかに不可能です。

ただし、これはチェックを行わないことを意味するものではありません。検出が容易な問題のクラスがある場合、それらをトラップすることは理にかなっています。

私はpylintとpycheckerには、どのような種類のエラーが発生するのかよく分かりません。私が言ったように、私はPythonにはとても慣れていません。

これらの静的解析プログラムは便利です。しかし、私は、コンパイラの機能を複製しない限り、コンパイラは静的チェッカよりもプログラムに関する情報を常に知る立場にあると信じています。可能であれば、これを利用してエラーを減らすのは無駄です。

アップデート2:

cdleary - 理論的には、私はあなたに同意は、静的アナライザは、コンパイラができることを、検証を行うことができます。そして、Pythonの場合は、十分でなければなりません。

しかしコンパイラが複雑な場合(特にコンパイルの方法を変更するプラグラムがたくさんある場合や、Perlのようにコンパイル時にコードを実行できる場合)、スタティックアナライザはコンパイラ/インタプリタを使用して解析を行います。

コンパイル時の複雑なコンパイラと実行コードの話は、私のPerlバックグラウンドを示しています。

私の理解は、Pythonにはプラグマがなく、コンパイル時に任意のコードを実行できないということです。したがって、私が間違っていたり、これらの機能が追加されたりしない限り、スタティック・アナライザの比較的単純なパーサで十分です。確かに、実行ごとにこれらのチェックを強制することは有益です。もちろん、私はこれを行う方法はプラグマを使用しています。

プラグマをミックスに追加すると、滑りやすい斜面が始まりました。アナライザーの複雑さは、プラグマで提供する力と柔軟性に比例して大きくなる必要があります。あなたが慎重でないなら、あなたはPerlのように巻くことができます。そして、 "ただPythonだけがPythonを解析できます"と私は見たくない未来です。

たぶんコマンドラインスイッチを強制的に静的解析を追加するためのより良い方法だろう。私はそれがPerlのようなコンパイル時の挙動をいじくることができないことを言うとき)

(決してPythonの機能を反論するつもりかできる。私はこれが慎重に考慮された設計決定であることを勘案し、その中に知恵を見ることができます。コンパイル時のPerlの非常に高い柔軟性は、IMHOであり、言語の大きな強さとひどい弱点です。私はこのアプローチでも知恵を見ています。)

+0

これを行うことができるpylintやpycheckerのような静的チェッカーがあります。 –

+2

Pythonは、用語を使用するコードを実行時に "拒否"します。まともなエディタは、perlとpythonの両方でこのような間違いを避けるのに役立ちます - これはポイントです - あなたのソースコードに意図しないエラーが含まれないようにします。 – popcnt

+0

のpythonからこの例を参照してください。 >>> strict_is_for_those_with_worthless_code_editorsの= 'yes' に >>> strict_Is_god + = 'RUN TIME FATAL ERROR' トレースバック(最新の呼び出しの最後):中 ファイル ""、ライン1、? NameError:name 'strict_Is_god'が定義されていません >>> – popcnt

1

私は、宣言されていないヴァルへの参照を検出することに本当に気を付けることがわかりました。 EclipseはPyDevを介したpylint統合を備えていますが、pylintは完璧ではありませんが、それは合理的な仕事です。

これはPythonの動的性質に反するもので、私のコードが何かについて賢明になると、時折#IGNOREを追加する必要があります。しかし、それは私がそれに満足していることがまれにしか起こらないことがわかります。

しかし、私はいくつかのpylintのような機能がコマンドラインフラグの形で利用できるようになっているのが分かりました。 Python 2.xと3.xのコードの間の非互換性の点を特定するPython 2.6の-3スイッチのようなものです。

+1

ええ、これは私が思っていたラインに沿っています。通常のインタプリタに「厳格な」コンパイルを有効にする追加のフラグを付けてラップします。私はこのようなことは全く見たことがないが、Perlの思想家はそれが必要/望ましいと考える傾向がある。 Pythonの思想家は気にしない傾向があります。どうして気にしないの? – cdleary

4

このオリジナルの回答は正しいですが、現実的には の状況を説明していません。

There exist static analysis tools for Python, but compile time checks tend to be >diametrically opposed to the run-time binding philosophy that Python embraces.

何厳格な使用」はPerlで提供することはスペルミス または変数名は(通常は)コンパイル時にキャッチされることを保証する機能です。これにより、コード の信頼性が向上し、開発がスピードアップします。しかし、そのようなことをする価値があるためには、 変数を宣言する必要があります。そして、Pythonスタイルはそれを妨げるようです。

あなたはあなたが作ったと思っ割り当てが行われ、または 式が予期しない値に解決すると思われることをされていないこと 実行時に気づくまで、だから、Pythonでは、あなたはスペルミスの変数を知ることはありません。このようなエラーをキャッチすることは、特にプログラムが大きくなるにつれて、そして人々が他人によって開発された コードを維持することを余儀なくされると、時間がかかるので、 になります。

JavaおよびC/C++では、さらにタイプチェックが行われています。その動機は実用的で、哲学的ではなく です。できるだけ早くできるだけ多くのエラーをキャッチするにはどうしたらいいですか? 各言語は、特定の戦略をとり、それに基づいて実行するように思われます。実行時バインディングがサポートされていないPerlのような言語では、 は、開発を容易にするために 'use strict'を利用するのが理にかなっています。

+0

これは、例えばJavaの場合よりも、はるかに少ないPythonで痛いです。 LongNamedFunctionNeededInJavaでタイプミスをすると、簡単には見えません。仮名冬モジュール(冬のインポートuser_nameから)からインポートしたuser_nameにタイプミスをした場合、そのことをほぼ一度に見つけ出すことができます。それは読み込み時に表示されます。なぜなら、これは通常、読み込む場所ですからです。名前空間の使用に至るまで:コードを読みやすくすることができます。 –

1

Perlでは 'strict strict'を使わないで大きなプログラムを書くことは非常に難しいです。 'use strict'を指定しないと、変数を再度使用し、文字を残してスペルを間違えた場合、プログラムは引き続き実行されます。テストケースがなくても結果を確認することはできません。そのようなエラーは決して見つけられません。この理由により、なぜあなたが間違った結果を得ているのかを見つけるのは、非常に時間がかかることがあります。

私のPerlプログラムの中には、5,000行から10,000行のコードが数十のモジュールに分割されているものがあります。 「厳密に使う」ことなく、実際にプロダクション・プログラミングを行うことはできません。私は決して "可変宣言"を強制しない言語で生産コードを工場にインストールすることを許可しません。

これは、Perl 5.12.xがデフォルトの動作として 'use strict'を持つ理由です。あなたはそれらをオフにすることができます。

PHPでは、可変宣言の強制がないため、かなりの問題があります。だからあなたはこの言語の小さなプログラムに自分自身を制限する必要があります。彼らは:)言ったように

だけの意見...

0

PerlをabcParsing

は気ままな言語です。したがって、発表前に変数を使用することができます。例:var name "is_array"を使用して "is_arrby"をタイプすると、コンパイラーは "use strict"がなければエラーを報告しません。したがって、長いプログラムをperlでコーディングするときは、 "use strict"ステートメントを使用することをお勧めします。もちろん、1回のスクリプトを実行するための50行以下である必要はありません。

+1

私は混乱しています。ここではPythonやPerlについて話していますか? – ccjmne

+0

@ ccjmne、Hah、はい。私は、構文エラーがなければ、プログラムを構築するために何かをする多くの自由をperlが与えると思います。 Pythonでは、少し制限が、十分です... :) – BinDu

関連する問題