Technically Impossible

Lets look at the weak link in your statement. Anything "Technically Impossible" basically means we haven't figured out how yet.

きれいなPythonプログラミング

BeyondTheBasicStuffWithPython

きれいなPythonプログラミング: クリーンなコードを書くための最適な方法 Compass Booksシリーズ
原題は『Beyond the basic stuff with Python』、初心者状態を超えていくための裏付けとなる知識を紹介している書籍だ。「the basic stuff」が示唆する、いわゆる駆け出しエンジニアのようなプログラマにもおすすめだが、むしろチームや部門で購入し、輪読することで、より有意義に機能する書籍と感じた。

邦題は「きれいなプログラミング」とあるように、プログラマ個人が意識するとよい作法の様なニュアンスを漂わせているが、実際にはプログラマ個人に限定するよりも、共に業務を担当するグループ内で暗黙に共有しておくと相乗効果が発揮され、より効果的に作用する知識が網羅されている。

それは例えば、べからず集やアンチパターン、誤解しやすい事柄にまつわる知識だ。このような知識をメンバーが事前に共有しておけば、特にレビューでの説明、根拠や裏付けとして、暗黙かつ効果的に作用するからだ。

本書は次の三部で構成されている。

PART3

まずPART3に触れておく。ここは少々、補足的な意味合いのある章だ。それは冒頭の説明に表れている。

Pythonでは必ずしもOOPの機能を使う必要はありません。

よりシンプルな関数やモジュールの方がうまくいくのにクラスを書いてしまう

そうは言いながらも、ではどうすればよいのか?について、本書では触れていないのだ。この章で紹介されている内容は、あくまでのPythonでのオブジェクト指向であり、おそらくほとんどのユーザーには、あまり必要とされない情報だ。

本書の肝はPART2にあり、特にWindowsユーザーにとってPART1が有用に機能するのが、本書の構成だ。

PART1

PART1は、環境変数やフォルダ構成、コマンド操作について触れられている。
珍しいのが、特にWindows環境に対しての言及が多いことだ。だからこそなのだが、環境変数の取扱には注意を要するだろう。それは、単一のPC内に、複数の異なるPython環境が導入される可能性があるからだ。これに伴うリスクについて本書は触れていない。具体的には、

迂闊に環境変数を定義すると、想定とは違うPythonが動作するリスクが生じるのだ。
実際、AnacondaはWindowsでの環境変数設定を推奨しておらず、次のようにコンソールごとに環境変数を定義して起動するよう工夫している。

📜Anaconda Powershell Promptの起動オプション

%windir%\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy ByPass -NoExit -Command "& 'C:\myapp\anaconda3\shell\condabin\conda-hook.ps1' ; conda activate 'C:\myapp\anaconda3' "


📜conda-hook.ps1での環境変定義

$Env:CONDA_EXE = "C:/myapp/anaconda3\Scripts\conda.exe"
$Env:_CE_M = ""
$Env:_CE_CONDA = ""
$Env:_CONDA_ROOT = "C:/myapp/anaconda3"
$Env:_CONDA_EXE = "C:/myapp/anaconda3\Scripts\conda.exe"
$CondaModuleArgs = @{ChangePs1 = $True}
Import-Module "$Env:_CONDA_ROOT\shell\condabin\Conda.psm1" -ArgumentList $CondaModuleArgs

Remove-Variable CondaModuleArgs

PART2

本書の最大のポイントであり、グループ内で共有されることで相乗効果を発揮するのがPART2だ。最もボリュームのある章ではあるものの、話題は小分けされており、関心のある話題だけに目を通すこともできる。
ここで紹介されている話題の中心は、べからず集、アンチパターン、誤解しやすい事柄だ。以下に挙げる話題は、その一部だ。

  • range()ではなくenumerate()を使う
  • デフォルト引数に可変値を使用しない
  • 文字列連結で文字列を作らない
  • sort()にアルファベット順のソートを期待してはいけない
  • !=演算子を連鎖させない
  • 256は256だけれども257は257ではない

「なぜそれではいけないのか」、「なぜそうではないのか」といった疑問が、どれか一つに対しては浮かんだのではないだろうか。その理由が気になった場合、読んで損はない書籍だ。特定の疑問が解消するだけなく、他の話題についても同様の意外性を持って楽しむことができるはずだ。

例えば「!=演算子を連鎖させない」だ。これは、次のような記述を避けるべきであることに触れている。

a != b != c

この記述を理解しやすいように書き直すと、次のようになる。

(a != b) and (b != c)

そして、ここまで書き直して気付くかもしれないことがある。本来想定していたのは、a, b, cが全て異なる値を取ることだったのだろう。しかし、この記述ではa, cが等しい場合にもTrueとなるのだ。実際に次のコードを試してみると良い。

a = 1
b = 2
c = 3

print(a != b != c)  #Trueを返す
print(a == c)

a = 3

print(a != b != c)  #Falseを返すはず?
print(a == c)

このように勘違いを生みやすく、結果としてバグを生じやすい書き方、なぜそうなるのかという知識、情報は、それを個人の内にだけとどめておくだけではなく、メンバー間で共有されることで、より有効に機能すると思うのだ。

このような知識がチーム内で共有されていれば、レビューでの指摘や説明における、情報や知識の非対称性に伴うつまづきも解消されていくだろう。少なくとも蘊蓄披露と邪推されるような場面も減るはずだ。