web-dev-qa-db-ja.com

pythonにはperlのように「use strict;」と「use warnings;」がありますか?

私はPerlとpythonを学んでいます...同時に、設計ではなく、やらなければなりません。

質問:

Perlスクリプトでは、txtの先頭で使用します(以下を参照)。

#!/usr/bin/env Perl

use strict;
use warnings;

pythonスクリプトのルーチンで行うべきことはありますか?

51
jon_shep

おそらくここでのコメントのノイズを少し回避する答えを提供するために、別のものを試してみます。

元の質問の2つのプラグマは、実際には次のように展開されます。

use strict "vars";
use strict "refs";
use strict "subs";
use warnings;

それぞれに順番に答えるには:

  • use strict "vars"の効果は、最初に変数が存在することを宣言せずに、コンパイル時エラーが変数を参照するようにすることです(C、C++、Javaなどのより静的な言語のデフォルトなど)。 Pythonには変数が存在することを宣言する特定の構文がないため、同等のものはありません。Python tが最初に存在します。この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;
}

多少工夫された例ですが、これはprintfステートメント内で初期化されていない値を使用することに関する警告を無効にし、他の警告を他のすべてで有効にしたままにするno warnings 'uninitialized'の使用を示しています。


要約すると、Pythonにはuse strictまたはそれに相当するものはありません。提供される安全機能はPython言語であり、use warningsがありません。提供する機能はファイルレベルでのみ有効であり、スコープごとに選択的に有効または無効にすることはできません。


編集:実際にPythonには制御可能な警告フラグがあり、必要に応じて有効または無効にできます。

52
LeoNerd

他のユーザーが投稿したように、Pythonには厳密なプラグマはありません。これは、私の意見では最大の欠陥の1つです。さらに、深刻なプログラミングプロジェクトでは、私はまだPerlを使用しています。

間違いなく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 __== '__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つです。

28
Rodney Kadura

警告をオンにしてPythonを実行するには:

python -W all file.py

に応答して:

pythonスクリプトのルーチンで行うべきことはありますか?

一般的に、コードが PEP 8 に準拠していることを確認することをお勧めします。別の答えで示唆されているように、これをプログラムで行うことができます。

pip install pep8 && pep8 file.py
8
Jian

LeoNerd'sは、Pythonに「厳密な使用」または「警告の使用」がない理由についての優れた説明を提供します。

に答えて:

pythonスクリプトのルーチンで行うべきことはありますか?

Pylintなどの静的コードアナライザーや、pep8などのコードフォーマットチェックを通じてコードを実行することに興味があるかもしれません。

潜在的な問題を見つけ、警告にフラグを立てるのに役立ちます。彼らはあなたのコードのフォーマットについても多くのことを言っています。

それらの使用の妥当な根拠 そして、関連するStackoverflowの質問 here および here です。

5
Sean

実際に同等のものはありません。 Pythonの設計は時間とともに進化しており、多くの変更が(特に3.xで)行われ、言語のデフォルトが開発者がデフォルトで望んでいるものになるようにしました。機能が存在することは非常にまれですが、オプションのフラグになります。

これはおそらく The Python of Zen's 'である必要があります-できれば1つだけである必要があります-それを行うための明白な方法です。'Pythonの設計読みやすさに焦点を当てており、さまざまな方法を実行したり、言語の動作方法を変更したりすると、コードが読みにくくなります。

最も近いのは、 __future__ 古いバージョンのPython新しいバージョンから古いバージョンにいくつかの修正/新機能を導入するために(デフォルトでは整数から浮動除算への除算など)。これはデフォルトの動作を改善して、標準的なケースでより賢明であるという感覚。

編集:私は、この投稿をPerlに対する攻撃とみなしているPerlユーザーから怒りを集めたようです。 Perlは素晴らしい言語です。私の最初の投稿では、不適切な表現を使用しているだけであり、その説明では明確ではありませんでした。私は明確にしようとしました。

0
Gareth Latty