RubyエンジニアがPythonコードを1週間書いた感想
はじめに
Xbit Advent Calendar 2022 24日目の記事です。
シフト管理SaaSであるらくしふを提供するクロスビットのバックエンドではRailsを採用することが多いですが、一部Pythonで書かれたAPIも存在します。WebフレームワークにはFastAPI、ORMにはSQLAlchemy、静的型解析にはmypyを使っています。
私はここ数年はRubyやTypeScriptでコードを書くことが多いですが、今回初めてPythonで書かれたプロダクトを触る機会がありましたので、その際に感じた点の中からいくつかピックアップしてみます。
リスト(辞書)内包表記に慣れるのが一番大事
Pythonといえばそう、リスト(辞書)内包表記ですね。list, dict, set など便利なデータ構造を揃えているPythonですが、それらを操作する際は多くのエンジニアに馴染み深いforループは使わないことが多いようです。
例えばPythonで通常のforループを使ったリスト操作をするこちらのコードは、
numbers = [1, 2, 3, 4, 5]
result = []
for n in numbers:
if n > 2:
result.append(n)
result
# [3, 4, 5]
以下のリスト内包表記に置き換え可能です。
numbers = [1, 2, 3, 4, 5]
result = [n for n in numbers if n > 2]
# [3, 4, 5]
初めてこういったコードを見た時は「え、、っと。。え、あ、、ん?forの前に変数があって、それから、、ifが後ろにある???」となりました。が、一日くらい書いているうちに慣れてくるので問題ありません。
これと同じようにdictionaryについても辞書内包表記を使って操作することが多いですが、一度慣れてしまえば案外快適なので、慣れるまで頑張りましょう。
pdbはいいやつだが信用ならない時もある
Pythonコードのデバッグに使われるpdbは基本的によく動いてくれますが、たまに?となる場合があるので注意です。例えば、
(pdb) foo
2
(pdb) [n for n in [1, 2, 3, 4, 5] if n > foo]
*** NameError: name 'foo' is not defined
といった風に確かに存在する変数なのになぜかNameErrorが発生することがありました。社内の有識者に聞いてみたところ、
とのことでした。一応の回避策はこちらに書かれています。
また先ほどの有識者曰くこれ以外にも、
という罠もあるようです。
mypyはいいやつだが信用ならない時もある
静的型解析で使われるmypyも基本的にはよく動いてくれますが、たまに?となる場合があるので注意です。例えば以下コードのように関数定義の返り値の型と実装が不一致の場合、
# foo.py
def foo() -> str:
return 777
mypyを実行するとエラーになってくれます。※以下はpoetryを使っている前提です。
# poetry run mypy foo.py
foo.py:2: error: Incompatible return value type (got "int", expected "str")
Found 1 error in 1 file (checked 1 source file)
ですが、ある関数とその呼び出し側コードが異なるmoduleに存在していて、かつ型の不一致がある場合はエラーになってくれません。
# foo.py
def foo() -> int:
return 777
# call_foo.py
from namespace.foo import foo
def call_foo() -> str:
return foo()
このような状況でmypyを実行すると、
# poetry run call_foo.py
Success: no issues found in 1 source file
という風にSuccessになってしまうので、mypyを使った静的型解析を過信はしない方が良いでしょう。
Railsと比べると書くコード量は多い(が楽しい)
これは完全に私個人の感想になりますが、過去数年間Railsを使ったコードばかり書いている人は同じように感じることもあるかと思います。箇条書きすると以下のような感じです。
- 「Railsと比べると書くコード量が多いなあ。特にDB操作周り。」
- 「しかしそれはPythonのライブラリが特にそうだと言うよりは、Rails(というかActiveRecord)が異常にシンプルに書けるAPIを備えているだけでは?」
- 「そう考えるとRails(というかActiveRecord)は偉大だなあ。」
- 「PythonのFastAPIは基本的に薄いし、SQLAlchemyはActiveRecordほどシンプルには書けないなあ。」
- 「とはいえたまにはPythonも悪くないなあ。」
- 「なぜなら、Railsのアプリケーション設計はある程度決まり切った設計パターンのようなものがある気がするけれど、Python+FastAPIだと、例えばレイヤードアーキテクチャとかを採用してプロジェクトに適した形にチューニングする、みたいな自由さがあるのでいいな。」
さいごに
株式会社クロスビットでは、デスクレスワーカーのためのHR管理プラットフォームを開発しています。一緒に開発を行ってくれる各ポジションのエンジニアを募集中です。
Discussion