検索
連載

[Pythonクイズ]PEP 8準拠の書き方がどれか分かる? 全部分かればLLM超えかもPythonステップアップクイズ

PEP 8はPythonのコーディングスタイルガイドとしては最も知られています。従うべきかどうかは時と場合によりますが、ちゃんと覚えているかどうかをこのクイズで確認してみましょう。

PC用表示 関連情報
Share
Tweet
LINE
Hatena
「Pythonステップアップクイズ」のインデックス

連載目次

PEP 8に従った書き方になっているのはどれかな?
PEP 8に従った書き方になっているのはどれかな?

【問題】

 以下に示す選択肢1から選択肢4のコードの中でPEP 8に準拠した書き方になっているものを挙げよ(ただし、1文字の変数名についてはここではPEP 8に準拠しているかどうかは問わないものとする)。

# 選択肢1
res = func0( arg0, arg1 )

# 選択肢2
s = data[lower+n : upper+n]

# 選択肢3
x , y = 0 , 1

# 選択肢4
var_name = 0
a        = 1
b        = 2

PEP 8に従った書き方になっているのはどれかな?

ChatGPT/Claude/Geminiは正解できたかな?

 ChatGPT/Claude/Geminiという3つのLLMに上の問題の答えを聞いてみました。筆者(HPかわさき)が正解とする答えをくれたのは……。

LLMに聞いてみた結果
LLMに聞いてみた結果

 というわけで、正解したのは2つのLLM。どのLLMがハズしたかについてはこの記事の最後で明かすことにしましょう。

 ん? これが正解できれば、もしかしてそのLLMよりも……なーんちゃって。



かわさき

 どうもHPかわさきです。

 LLMとの戯れコーナーをこの独り言枠からちょっと外してみました。いいですね。適当なことを書けるところが復活したのは。とてもいいです。でも、今日は特に書くことがありません。

 今回はPythonクイズの「PEP 8(コードの書き方ルール)の理解度をチェック! 適切な書き方がどれか分かるかな?」に続くPEP 8クイズの第2弾です。皆さん、奮ってご参加ください。「思ったよりもカンタンになっちゃったかなー」と思ったのですが、上の通り、LLMの1つはうまいこと間違えてくれたのでちょっと安心しました。


【答え】

 PEP 8に準拠した書き方になっているのは選択肢2の「s = data[lower+n : upper+n]」です。

PEP 8に準拠しているのは選択肢2
PEP 8に準拠しているのは選択肢2

 既にお気付きでしょうが、今回はPEP 8の中でもコードへの空白文字(スペース)の入れ方についての問題となっています。何となく選択肢2もどうなの? という気にもなりますが、それについてはこの後で説明しましょう。

【解説】

 まずはPEP 8に従っているとした選択肢2について見ておきましょう。

s = data[lower+n : upper+n]

選択肢2のコード

 正直、あんまり見かけない書き方に感じる方が多いかもしれません。しかし、PEP 8の「Whitespace in Expressions and Statements」を見てみると、こんなことが書いてあります。

 However, in a slice the colon acts like a binary operator, and should have equal amounts on either side (treating it as the operator with the lowest priority).
 「しかし、スライスでは、コロンは2項演算子のように機能するので、その両側に空白文字を同じ数だけ置くべき(優先度が最低の演算子として扱う)」(筆者によるテキトー訳。以下同じ)。

 なるほど。でも、だからといって、コロンの両隣に空白文字を1個ずつ置きながら、「lowest+n」のように加算演算子の両隣には空白文字を置かないのはおかしく見えますよね。しかし、これについては同じくPEP 8の「Other Recommendations」に次のように書いてあるのです。

 If operators with different priorities are used, consider adding whitespace around the operators with the lowest priority(ies).
 「優先度が異なる演算子を使うときには、優先度が最も低い演算子の前後に空白文字を置くことを検討しよう」

 「スライスの中のコロンは優先度が最低の2項演算子と見なす」「1つの式中に優先度が異なる演算子があれば、一番低い優先度の演算子の前後に空白文字を置く」という2つのガイドの合わせ技で選択肢2の書き方はPEP 8に従っているといえるのでした。実際、「Whitespace in Expressions and Statements」の下には、よく似たコードが「Correct」として記載されています。

 その一方で、以下のコードもPEP 8に準拠している書き方の例として挙げられています。コロンの前後だけではなく+演算子の前後にも空白文字がありますが、これでもOKなようです。

ham[lower + offset : upper + offset]

コロンだけではなく、+演算子の前後にも空白文字があるがOK

 しかし、「Other Recommendation」では正しいコードの例と正しくないコードの例として以下が挙げられています。上ではOKとされていたパターンが下の例ではWrongになっています。

# Correct:
hypot2 = x*x + y*y
c = (a+b) * (a-b)

# Wrong:
hypot2 = x * x + y * y
c = (a + b) * (a - b)

優先度が一番低くなる2項演算子の前後にだけ空白文字を入れるのが正しい?

 筆者は、多くの場合、Wrongにある方の「2項演算子の前後には常に空白文字を入れる」スタイルでコードを書いちゃいますねぇ。PEP 8にもこうあります。

 A Foolish Consistency is the Hobgoblin of Little Minds
 「一貫性に対する過度なこだわりは、未熟な心に住み着いたマモノ」

 今述べたような普段のスタイルを変えるべきかどうかはともかく(以前から知ってはいたのですが、手癖のようなもので直していなかったのでした)、組織内で優先すべきガイドラインがあれば、それらに従うのはいうまでもありません。要は「取捨選択は自分で判断しよう」ということですね。

 と、深掘りするとタイヘンなことになりそうなので、そうはせずに「選択肢2はOK」ということにして、次に進みましょう。

 選択肢1がNGであることは比較的分かりやすいかと思います。

res = func0( arg0, arg1 )

選択肢1のコード

 PEP 8の「Whitespace in Expressions and Statements」には「不要な空白文字を避けること」として次のような状況が挙げられています。

 Immediately inside parentheses, brackets or braces:
 「かっこ、角かっこ、波かっこの直後(開き)と直前(閉じ)」

 「func0( arg0, arg1 )」では開きかっこの直後と閉じかっこの直前に空白文字があるのでダメですね。これは次のように書くべきです。

res = func0(arg0, arg1)

選択肢1のコードを修正したもの

 選択肢3も分かりやすいですね。

x , y = 0 , 1

選択肢3のコード

 選択肢3はカンマを使い「x , y = 0 , 1」のようにして、1行で複数の変数に複数の値を代入していますが、「Whitespace in Expressions and Statements」には空白文字を置かない場所として次のように書かれています。

 Immediately before a comma, semicolon, or colon:
 「カンマ、コロン、セミコロンの直前」

 上のコードではカンマの前にある空白文字が余計です。次のようなコードが推奨されています(といっても、カンマの前に空白文字を置く人はそれほどいない気がしています)。

x, y = 0, 1

選択肢3のコードを修正したもの

 最後の選択肢4は以下のようなコードでした。「=」の位置をそろえることで、コードが読みやすくなるパターンですね。

var_name = 0
a        = 1
b        = 2

選択肢4のコード

 ですが、PEP 8の「Whitespace in Expressions and Statements」ではこれまでと同様、余計な空白文字を避ける状況として以下が挙げられています。

 More than one space around an assignment (or other) operator to align it with another:
 「代入演算子(や他の演算子)の位置を揃えるために、その前後に2文字以上の空白文字を使うこと」

 つまり、代入演算子の位置をそろえてコードの見た目をよくするのは、Pythonでは推奨されていないということです。上のコードは次のように書くことが推奨されています。

var_name = 0
a = 1
b = 2

選択肢4のコードを修正したもの

 以上をまとめると次のようになります。

  • 選択肢1:開きかっこの直後、閉じかっこの直前の空白文字が不要→NG
  • 選択肢2:スライスのコロンは優先度最低の演算子として扱い、その前後には空白文字を入れる(かつ、優先度の高い演算子はギュッとまとめる)→OK
  • 選択肢3:カンマの直前の空白文字が不要→NG
  • 選択肢4:演算子の位置をそろえるための追加の空白文字が不要→NG

 よって、PEP 8に従っているのは選択肢2だけとなりました。


かわさき

 3つのLLM(ChatGPT、Claude、Gemini)のうち、間違えたのはどれだったと思いますか? 実はコーディングに強いというイメージがあるClaudeが間違えていました(もちろん、読者が自分で試すとそうはならない可能性もあることには注意しましょう)。彼の言い分をまとめると次のようになります。

  • スライス記法でコロンの前後のスペースが不統一(前にスペースあり、後にスペースあり、だが+演算子の前後にはスペースなし)
  • 正しくは「s = data[lower + n:upper + n] または s = data[lower+n:upper+n]」

 この「正しい」として提案してきた記法も間違っているのがお茶目です。では、彼がどの選択肢を「正しい」と答えたかというと……以下の通りです。

  • 選択肢4:代入演算子の前後に適切なスペースがある。PEP 8では、縦に揃えるための追加スペースは許可されている

 「うーーーん」となっちゃいますよね。そこで「PEP 8をちゃんと読んでいますか?」と尋ねたら、今度は正解が返ってきました。よかった。よかった。

 他の2つのLLMは、ちょっとあやふやなところもありましたが、PEP 8に従っているのは選択肢2であると正解を導き出していました(詳細は省略します)。


「Pythonステップアップクイズ」のインデックス

Pythonステップアップクイズ

Copyright© Digital Advantage Corp. All Rights Reserved.

[an error occurred while processing this directive]