Pythonの「それを行う唯一の方法」格言の具体例[終了]


34

私はPythonを学んでおり、PEP 20 The Zen of Pythonの次の点に興味があります。

明白な方法が1つあり、できれば1つだけである必要があります。オランダ人でない限り、その方法は最初は明らかではないかもしれませんが。

誰もこの格言の具体的な例を提供できますか?Rubyなどの他の言語とのコントラストに特に興味があります。Rubyの設計哲学の一部(Perlを起源とするのでしょうか?)は、それを行う複数の方法が良いことであるということです。誰もが各アプローチの長所と短所を示すいくつかの例を提供できますか。注:私はどちらが良いか(おそらく主観的すぎて答えられない)の答えではなく、2つのスタイルの公平な比較を求めています。

回答:


47

Perlのような言語と比較して、Pythonの制御構造の数は限られています。

  • のみifといいえunless
  • 唯一forのシーケンスを反復処理していないことforeachやC-スタイルfor
  • whileループごとに条件をチェックするだけで、no do-while
  • のみif-elifといいえswitch
  • コメント構造は1つしかあり#ません。すべての行について、前の行を見なくてもコメントアウトされているかどうかを確認できます。

また、ソースをインデントする方法はほぼ1つあります。創造的なインデントのほとんどの場合は、構文的に除外されます。

これにより、Pythonソースの解析が人間にとって簡単になります。

組み込み型と標準ライブラリでは、最小限の完全な試みがあります。

  • 可変リストには、唯一の組み込みlistタイプを使用します。ほとんどの操作ではO(1)であり、適切な実装を選択する必要はありません。
  • 不変リストの場合も同様に、tupleタイプを使用するだけです。
  • マップのdict場合、ほとんどの場合、非常に効率的な組み込みのみを使用します。どの実装を使用するかを考える必要はありません。

Python 3はこれを整数に拡張します。整数がどんなに大きくても、同じ型を使用し、強制を気にしません。

Pythonは、シンタックスシュガーを回避しようとします。しかし、時には明白な方法を明らかにするためだけに構文糖を追加します。「ではない」は特殊なケースif foo is not Noneであるif not (foo is None)ため、代わりに書くことができます。それでもfoo is not None読みやすく、誤解されることはありません。また、考える必要はありません。明白なことを書くだけです。

もちろん、Pythonでのより複雑なことのほとんどは、いくつかの方法で実行できます。宣言または単純なスロット割り当てによってメソッドをクラスに追加できます。さまざまな創造的な方法で関数に引数を渡すことができます。これは、言語の内部がほとんど公開されているからです。

重要なのは、常に最適な方法であるカバーオールケースがあることです。他の方法が存在する場合、それらは同等の代替手段(ifおよびunless)として追加されず、単に内部動作を公開するだけです。既知の最良のメカニズムを強化することにより、そのような代替手段は徐々にではあるが着実に廃止されます(排除されません!)。

デコレータは、AOP関数呼び出しをラップします。2.6より前では、__metaclass__マジックメンバーを使用してクラスのメタクラスを宣言する必要がありました。これにも同じデコレータ構文を使用できます。3.0より前には、バイト指向とUnicodeの2種類の文字列がありましたが、これらは誤って混在する可能性がありました。これで、唯一のUnicode strと唯一のbinary-transparentがありbytes、これらを誤って混在させることはできません。


3
念のため、"""コメント(docstrings)を忘れないでください。これらは複数行にわたっています。
-asthasr

8
三重引用符付きリテラルは、単一引用符と同じ文字列ですが、行末をエスケープせずに複数の行にまたがることができます。宣言直後の文字列リテラルはドキュメント文字列と見なされ、コメントではなく、通常は__doc__属性としてアクセスできます。暗黙的に隣接するリテラル、使用参加、使用、シングル、ダブル、トリプル引用:しかし、文字列はPythonは確かに多くの「右の方法」を提供した領域であるrなど、生のリテラルのために、
9000は、

1
私はsyrionのコメントはに関するました@ので、文字列「「」の真のされていない、「あなたは常に行はそれを見て、コメントされているかどうかを決めることができる」と考えています。
blubb

2
「これにより、Pythonソースの解析が人間にとって簡単になります。」<-それは主観的です
ジギー

2.7でメタクラス宣言はどのように変更されましたか?メタクラスの2.7ドキュメントでデコレータパターンが見つかりません。
ニックT

10

もう1つの例は次のとおり
len()です。すべてのシーケンスに存在するメソッドではなく関数です。あなたは、Javaと比較すれば、あなたは持っている.length.size().getSize()シーケンスの要素の数を見つけること、および他の方法。

別の例は、すべてのシーケンスに存在.join()するstringメソッドではなく、メソッドであるという事実です。結合パラメータがリスト、セット、内包表記、その他何でも機能するかどうかを知る必要はありません。


8

Cでは、変数の値を1つ増やすための多くの方法があります。

i++     // Post-increment, returns the number before the increment
++i     // Pre-increment, returns the number after the increment
i += 1 

それぞれがiby の値を増やします1が、それぞれがわずかに異なります。

Pythonでは、実際には1つの方法しかありません。1つ追加するだけです。

i += 1

そして、これを行うための構文的に有効な方法は複数ありi = i + 1ますが(例)、同じ副作用で同じことをしています。


1
私は専門家ではありませんが、その例は「それを行う唯一の方法」という考えに正確に違反しているようです。それを行うには2つの方法がありますが、どちらがより明白ですか?私の目には、最初の例はより明白ですが、2番目の例はもう少し簡潔ですが、非常に基本的なものを超えて進歩したプログラマーにとっては読みやすく、または明白です。あなたの答えをありがとう-それは思考のための良い食べ物です。
チャールズローパー

@Peter(および@Charles):実際にi = i + 1は、増分ではなく割り当てです。Pythonでは、増分はi += 1です。Cスタイルの言語では、書くことができi++++ii += 1
ジョシュK

2
「多くの混乱」コメントについてi += 1はわかりませんが、3つのCの例(見逃した、BTW)はすべて、まったく同じ結果を生成します。人々が混乱するのを見るのは、大きな式の一部として変数をプリインクリメントまたはポストインクリメントするときだけです。それは通常、言語リファレンスの適切なセクションを読むことですぐに修正されます。個人的には、文字列の5番目の文字を両方str[4]または*(str+4)で参照できるという事実を選びましたが、多分それは簡単すぎ
TMN

2
@TMN:max(i++, ++i)すぐに修正できない場合など。Cには多くの「未定義」および「実装依存」の動作ケースがありますが、すべて正当な理由がありますが、それぞれが落とし穴を作る可能性があります。
9000

@TMN:4 [str]は言うまでもありません(Cで有効、C ++では無効かもしれません)。
Vatine

6

別の可能性として、リストの内包表記があります。Pythonでは、これ行うことができます。

new_list = []
    for item in list_of_items:
       if item < 10:
           new_list.append(item)

しかし、これを行う「明白な」方法(オランダ人であるか、Pythonに精通している場合)は、リストを理解することです。

new_list = [item for item in list_of_items if item < 10]

それはより短く、new_listは1ステップで作成され、より高速に実行され、エレガントです。マイナス面としては、それほど明確ではないと感じる人もいるかもしれませんが、慣れると、それは同じくらい明確になります。


インデントとコードの場合:4つのスペースを先頭に追加すると、インデントが考慮されます。
インカ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.