私はperlとpythonを学んでいます...同時に、私の設計ではありませんが、それは行われなければなりません。
質問:
perlスクリプトでは、txtの先頭で使用します(以下を参照)。
#!/usr/bin/env perl
use strict;
use warnings;
Pythonスクリプトのルーチンで実行する必要があることはありますか?
ここでのコメントのノイズを少し回避する答えを提供するために、別の回答を試してみます。
元の質問の2つのプラグマタは、実際には次のように拡張されます。
use strict "vars";
use strict "refs";
use strict "subs";
use warnings;
それぞれに順番に答えるには:
use strict "vars"
最初に変数が存在することを宣言せずに、コンパイル時エラーが変数を参照するようにすることです(C、C ++、Javaなどのより静的な言語のデフォルトなど)。Pythonには変数が存在することを宣言するための特定の構文がないため、同等のものはありません。Pythonで名前を割り当てると、最初に存在しなかった場合は常に名前が作成されます。この機能にstrict
はPythonに相当するものがなく、提供される安全性を再現することはできません。例えば:
$ perl -c -e 'use strict "vars"; $foo = 1'
Global symbol "$foo" requires explicit package name at -e line 1.
-e had compilation errors.
$ perl -c -e 'no strict "vars"; $foo = 1'
-e syntax OK
use strict "refs"
、変数自体への参照として(既存または新規の)変数の名前を含むプレーン文字列の使用を禁止することです。Pythonはこれを行わないため、無効にする必要はありません。例えば:
$ perl -e 'use strict "refs"; ${"message"} = "hello"; print $message'
Can't use string ("message") as a SCALAR ref while "strict refs" in use at -e line 1.
$ perl -e 'no strict "refs"; ${"message"} = "hello"; print $message'
hello
use strict "subs"
、コンパイル時に、存在しないことがわかっている関数を呼び出そうとすることです。Pythonはそのようなチェックを実行せず、そのような機能を有効にする方法がありません。例えば:
$ perl -c -e 'use strict "subs"; foo'
Bareword "foo" not allowed while "strict subs" in use at -e line 1.
-e had compilation errors.
$ perl -c -e 'no strict "subs"; foo'
-e syntax OK
use warnings
、以前のバージョンでデフォルトであった、時には望ましい場合がある、または決して良い考えではなかったが厳密にはエラーではない、さまざまなカテゴリの動作のコンパイルと実行時の両方でより多くの警告を有効にすることです。たとえば、初期化されていない値を数値として使用すると、通常は警告が表示されますが、元々は警告が表示されませんでした。例えば:
$ perl -e 'use warnings; my $u; print 2 + $u'
Use of uninitialized value $u in addition (+) at -e line 1.
2
$ perl -e 'no warnings; my $u; print 2 + $u'
2
ついに; Pythonには同様の機能があるというコメントがいくつかあります__future__
。ただし、後者のほとんどは字句スコープであり、必要に応じて小さなスコープ内で有効または無効にできるため、これはPerlのプラグマと同様と見なすべきではありません。ここで、Python__future__
はソースファイル全体に対してのみ有効になっています。
例えば。
use strict;
use warnings;
my $total;
$total += count_things($_) for @list;
{
no warnings 'uninitialized';
printf "The total is %d\n", $total;
}
やや工夫された例ですが、これは、他のすべての場所で他の警告を有効にしたままno warnings 'uninitialized'
、ステートメント内で初期化されていない値を使用することに関する警告を無効にするための使用法を示しています。printf
要約すると、Pythonuse strict
には、それが提供する安全機能のいずれかが必須であるか、Python言語で使用できないため、またはほぼ同等のものがなく、。もありませんuse warnings
。提供する機能はファイルレベルでのみ有効になり、スコープごとに選択的に有効または無効にすることはできません。
編集:実際、Pythonには制御可能な警告フラグがいくつかあり、必要に応じて有効または無効にできることが通知されました。
他のユーザーが投稿しているように、Pythonには厳密なプラグマはありません。そして、これは私の意見では、その最大の欠点の1つです。さらに、それは私が本格的なプログラミングプロジェクトのためにまだPerlを使用している理由の1つです。
この声明に恥ずかしがるPython愛好家がいることは間違いありません。厳密にする必要はないと言う人もいます。私は、これを言う人は通常、厳密にあなたを買うものを知らないことがわかります。Pythonの次のコードブロックについて考えてみます。
def Main():
print(GetPrice(100,"Alaska"))
print(GetPrice(100,"Florida"))
print(GetPrice(100,"Michigan"))
print(GetPrice(100,"Wisconsin"))
def GetPrice(UnitPrice,State):
StateSalesTaxRate = 0
if State == "Alabama": StateSalesTaxRate = 0.04
if State == "Alaska": StateSalesTaxRate = 0
if State == "Arizona": StateSalesTaxRate = 0.056
if State == "Arkansas": StateSalesTaxRate = 0.065
if State == "California": StateSalesTaxRate = 0.075
if State == "Colorado": StateSalesTaxRate = 0.029
if State == "Connecticut": StateSalesTaxRate = 0.0635
if State == "Delaware": StateSalesTaxRate = 0
if State == "Florida": StateSalesTaxRate = 0.06
if State == "Georgia": StateSalesTaxRate = 0.04
if State == "Guam": StateSalesTaxRate = 0.04
if State == "Hawaii": StateSalesTaxRate = 0.04
if State == "Idaho": StateSalesTaxRate = 0.06
if State == "Illinois": StateSalesTaxRate = 0.0625
if State == "Indiana": StateSalesTaxRate = 0.07
if State == "Iowa": StateSalesTaxRate = 0.06
if State == "Kansas": StateSalesTaxRate = 0.0615
if State == "Kentucky": StateSalesTaxRate = 0.06
if State == "Louisiana": StateSalesTaxRate = 0.04
if State == "Maine": StateSalesTaxRate = 0.055
if State == "Maryland": StateSalesTaxRate = 0.06
if State == "Massachusetts": StateSalesTaxRate = 0.0625
if State == "Michigan": StateSalesTexRate = 0.06
if State == "Minnesota": StateSalesTaxRate = 0.06875
if State == "Mississippi": StateSalesTaxRate = 0.07
if State == "Missouri": StateSalesTaxRate = 0.04225
if State == "Montana": StateSalesTaxRate = 0
if State == "Nebraska": StateSalesTaxRate = 0.055
if State == "Nevada": StateSalesTaxRate = 0.0685
if State == "New Hampshire": StateSalesTaxRate = 0
if State == "New Jersey": StateSalesTaxRate = 0.07
if State == "New Mexico": StateSalesTaxRate = 0.05125
if State == "New York": StateSalesTaxRate = 0.04
if State == "North Carolina": StateSalesTaxRate = 0.0475
if State == "North Dakota": StateSalesTaxRate = 0.05
if State == "Ohio": StateSalesTaxRate = 0.0575
if State == "Oklahoma": StateSalesTaxRate = 0.045
if State == "Oregon": StateSalesTaxRate = 0
if State == "Pennsylvania": StateSalesTaxRate = 0.06
if State == "Puerto Rico": StateSalesTaxRate = 0.105
if State == "Rhode Island": StateSalesTaxRate = 0.07
if State == "South Carolina": StateSalesTaxRate = 0.06
if State == "South Dakota": StateSalesTaxRate = 0.04
if State == "Tennessee": StateSalesTaxRate = 0.07
if State == "Texas": StateSalesTaxRate = 0.0625
if State == "Utah": StateSalesTaxRate = 0.0595
if State == "Vermont": StateSalesTaxRate = 0.06
if State == "Virginia": StateSalesTaxRate = 0.053
if State == "Washington": StateSalesTaxRate = 0.065
if State == "West Virginia": StateSalesTaxRate = 0.06
if State == "Wisconsin": StateSalesTaxRate = 0.05
if State == "Wyoming": StateSalesTaxRate = 0.04
return(UnitPrice*(1+StateSalesTaxRate))
if __name__ == '__main__': Main()
このコードは、消費税を含む購入のコストを計算します。確かに、これを行うためのより効率的な方法がありますが、それは単なる例示です。
それで、あなたはコードに何か問題がありますか?いいえ?実行してみてください。あなたが得るとき:
100
106.0
100
105.0
それでも問題はありませんか?次に、あなたはあなたが知っているよりも大きな問題を抱えています。Perlでレンダリングされた同等のコードは次のとおりです。
use strict;
sub Main
{
print GetPrice(100,"Alaska"), "\n";
print GetPrice(100,"Florida"), "\n";
print GetPrice(100,"Michigan"), "\n";
print GetPrice(100,"Wisconsin"), "\n";
}
sub GetPrice
{
my($UnitPrice,$State) = @_;
my $StateSalesTaxRate = 0;
$StateSalesTaxRate = 0.04 if $State eq "Alabama";
$StateSalesTaxRate = 0 if $State eq "Alaska";
$StateSalesTaxRate = 0.056 if $State eq "Arizona";
$StateSalesTaxRate = 0.065 if $State eq "Arkansas";
$StateSalesTaxRate = 0.075 if $State eq "California";
$StateSalesTaxRate = 0.029 if $State eq "Colorado";
$StateSalesTaxRate = 0.0635 if $State eq "Connecticut";
$StateSalesTaxRate = 0 if $State eq "Delaware";
$StateSalesTaxRate = 0.06 if $State eq "Florida";
$StateSalesTaxRate = 0.04 if $State eq "Georgia";
$StateSalesTaxRate = 0.04 if $State eq "Guam";
$StateSalesTaxRate = 0.04 if $State eq "Hawaii";
$StateSalesTaxRate = 0.06 if $State eq "Idaho";
$StateSalesTaxRate = 0.0625 if $State eq "Illinois";
$StateSalesTaxRate = 0.07 if $State eq "Indiana";
$StateSalesTaxRate = 0.06 if $State eq "Iowa";
$StateSalesTaxRate = 0.0615 if $State eq "Kansas";
$StateSalesTaxRate = 0.06 if $State eq "Kentucky";
$StateSalesTaxRate = 0.04 if $State eq "Louisiana";
$StateSalesTaxRate = 0.055 if $State eq "Maine";
$StateSalesTaxRate = 0.06 if $State eq "Maryland";
$StateSalesTaxRate = 0.0625 if $State eq "Massachusetts";
$StateSalesTexRate = 0.06 if $State eq "Michigan";
$StateSalesTaxRate = 0.06875 if $State eq "Minnesota";
$StateSalesTaxRate = 0.07 if $State eq "Mississippi";
$StateSalesTaxRate = 0.04225 if $State eq "Missouri";
$StateSalesTaxRate = 0 if $State eq "Montana";
$StateSalesTaxRate = 0.055 if $State eq "Nebraska";
$StateSalesTaxRate = 0.0685 if $State eq "Nevada";
$StateSalesTaxRate = 0 if $State eq "New Hampshire";
$StateSalesTaxRate = 0.07 if $State eq "New Jersey";
$StateSalesTaxRate = 0.05125 if $State eq "New Mexico";
$StateSalesTaxRate = 0.04 if $State eq "New York";
$StateSalesTaxRate = 0.0475 if $State eq "North Carolina";
$StateSalesTaxRate = 0.05 if $State eq "North Dakota";
$StateSalesTaxRate = 0.0575 if $State eq "Ohio";
$StateSalesTaxRate = 0.045 if $State eq "Oklahoma";
$StateSalesTaxRate = 0 if $State eq "Oregon";
$StateSalesTaxRate = 0.06 if $State eq "Pennsylvania";
$StateSalesTaxRate = 0.105 if $State eq "Puerto Rico";
$StateSalesTaxRate = 0.07 if $State eq "Rhode Island";
$StateSalesTaxRate = 0.06 if $State eq "South Carolina";
$StateSalesTaxRate = 0.04 if $State eq "South Dakota";
$StateSalesTaxRate = 0.07 if $State eq "Tennessee";
$StateSalesTaxRate = 0.0625 if $State eq "Texas";
$StateSalesTaxRate = 0.0595 if $State eq "Utah";
$StateSalesTaxRate = 0.06 if $State eq "Vermont";
$StateSalesTaxRate = 0.053 if $State eq "Virginia";
$StateSalesTaxRate = 0.065 if $State eq "Washington";
$StateSalesTaxRate = 0.06 if $State eq "West Virginia";
$StateSalesTaxRate = 0.05 if $State eq "Wisconsin";
$StateSalesTaxRate = 0.04 if $State eq "Wyoming";
return($UnitPrice*(1+$StateSalesTaxRate));
}
Main();
Perlの厳密なプラグマを有効にしないと、同じ出力が得られます。
100
106.0
100
105.0
ただし、strictをオンにすると、このPerlスクリプトを実行すると次のエラーメッセージが表示されます。
Global symbol "$StateSalesTexRate" requires explicit package name at line 37.
Execution aborted due to compilation errors.
両方の例の問題は、計算ラインの1つにタイプミスがあることです。ミシガン州の消費税を計算するために、「StateSalesTaxRate」の代わりに「StateSalesTexRate」を使用しています。Perlは、このバグを明示的に見つけて潰します。その間、Pythonは頭を回転させ、逆に見えます。
これは大したことです。このソフトウェアが、顧客のクレジットカードに請求する金額を計算するためにオンラインビジネスで使用されていると想像してください。ミシガン州の顧客が消費税のパスを取得していることに気付くまでにどのくらい時間がかかりますか?あなたがそうするとき、あなたは顧客に戻って「すみません、私たちはあなたからもっとお金が必要です」と言いますか、それともあなたは自分で損失を食べますか?
もちろん、このタイプのコーディングアルゴリズムを使用して消費税を計算している企業は、おそらくより大きな問題を抱えています。しかし、この例から、Perlの厳密なプラグマが何をするのか、そしてなぜそれがスクリプト言語の本質的な機能であると私や他の人が信じているのかがはっきりとわかります。
Pythonについて私が本当に気に入っていることはたくさんあります。PerlよりPythonを好む人がいる理由がわかります。しかし、私がPythonについて本当に嫌うことがいくつかあります。これは1つです。
警告をオンにしてPythonを実行するには:
python -W all file.py
に応答して:
Pythonスクリプトのルーチンで実行する必要があることはありますか?
通常、コードがPEP8に準拠していることを確認することをお勧めします。別の回答でほのめかされているように、これはプログラムで行うことができます。
pip install pep8 && pep8 file.py
LeoNerdは、Pythonに「usestrict」または「usewarnings」がない理由についての優れた説明を提供します。
に答えて:
Pythonスクリプトのルーチンで実行する必要があることはありますか?
pylintなどの静的コードアナライザーやpep8などのコードフォーマットチェックを介してコードを実行することに興味があるかもしれません。
それらは潜在的な問題を見つけ、警告にフラグを立てるのに役立ちます。彼らはまたあなたが興味があるかもしれないし興味がないかもしれないあなたのコードのフォーマットについて多くのことを言う必要があります。
ここにそれらの使用のまともな理論的根拠があります。そして、こことここに関連するStackoverflowの質問。
実際に同等のものはありません。Pythonの設計は時間の経過とともに進化し、言語のデフォルトが開発者がデフォルトで望んでいるものになるように、多くの変更が加えられました(特に3.xで)。機能が存在することは非常にまれですが、オプションのフラグです。
これはおそらく、PythonのZenの 「それを行うための明白な方法は1つ、できれば1つだけあるはずです」に帰着します。Pythonの設計は読みやすさに重点を置いており、さまざまな方法で物事を実行したり、言語の動作方法を変更したりすると、コードが読みにくくなります。
最も近いのは、Pythonの古いバージョンからのインポートで__future__
、新しいバージョンから古いバージョンへのいくつかの修正/新機能(デフォルトで整数から浮動小数点への除算など)を導入することです。これは、デフォルトの動作が標準の場合により賢明になるように改善されているという意味で似ています。
編集:私はこの投稿をPerlへの攻撃と見なしているperlユーザーから怒りを集めたようです-それはそのように意図されたものではありませんでした。Perlはすばらしい言語です。私の元の投稿では、不適切な表現が使用されており、説明が明確ではありませんでした。私は明確にしようとしました。
コンパイル時のエラーではありませんが、Pythonには、Perlの「usestrict」と同じタイプのエラーを識別できる多くのリンターがあります。
次の名前のPythonファイルについて考えてみますtmp.py
。
def foo():
a = 1
b = 2
return a
flake8 tmp.py
戻ります:
tmp.py:13:5: F841 local variable 'b' is assigned to but never used
に加えてflake8
、mypy
より高度な型チェックをチェックして、pylint
特定のコーディングスタイルを適用します。他のプログラミング言語と同様に、コードベースで複数のリンターを使用することを妨げるものは何もありません。実際、リンターごとに焦点が異なるため、これをお勧めします。