筆者はいつも構想→コーディング→デプロイまで行っているので、技術選定も自身で行っています。
その中で、既に昔話の域になりますが、ご存じ動的型付け言語Pythonを選定して開発がクラッシュ(頓挫)した話と教訓をお話ししてみようと思います。
※後述しますが、動的型付け言語やPythonがダメということでなく、得意分野が違う、というお話をします。念のため。
◇目次
先に結論:技術選定に興味本位を持ち出さないこと。また、動的型付け言語はミドルサイズ以上のプロジェクトに不向き。
後段で述べる通り、技術選定の場面で興味本位を持ち出してしまったことが最大の失敗要因と言えます。
今回は一部署の内部プロジェクトでしたのでまだマシでしたが、受託や社運を賭けたプロジェクトなど責任ある立場で開発を行うときは、既に知見・経験がある技術を採用するというのは当たり前ですが大切です。
また、Quoraの下記記事での引用にもある通り、大規模なチームでも、Python等の動的型付け言語はミドルサイズ以上のプロジェクトは向いていない、という認識があるようです。
あり得ません。速度が遅く、チームでのエンジニアリングに骨が折れ、大規模なコードベースには不向きで、正しいことの証明が非常に困難だからです。これが、PythonではなくJavaがGmailを支えている理由であることはほぼ間違いありません。
引用元:Quora:Quora:なぜGoogleはGmailにPythonではなくJavaを採用しているのでしょうか?(外部リンク)
ことの始まり:何を作ろうとしていたのか
とある社内プロジェクトで、以下のような中規模程度の内部用業務用システムを開発することになり、私の方で技術選定・設計・開発を行うこととなりました。
- UI+CURD+データベース
- それなりに複雑なビジネスロジック計算を伴うバッチ処理
- ユーザーは1拠点内の社員のみ
UIの組み立て手間や共有性も考慮して、内部ネットワークで使用可能なWebアプリとして構築することにしました。
失敗の瞬間:興味本位でPython+Djangoを選定
当時の私は、Webアプリ構築で知っている技術はMicrosoftが作っているASP.NET(C#)のみでした。
これを使って構築を始めても良かったんですが、せっかく内部での開発を始めるのだから、別の技術を試してみたいという目論見がありました。(これが失敗の根源!)
そんなとき、たまたま目に留まったのが、PythonのWebフレームワーク「Django」です。Pythonで動くフレームワークとしてはFlaskなどと並び代表的なWebフレームワークであり、一通りの機能がそろった優れものです。
これならPythonでの本格的なコーディングもできるし(この時点ではPythonも書くのは初めて!)、新しいフレームワークも体験できるし一石二鳥だな!というノリで開発を開始してしまいました。
見出しにもある通り、これが失敗のすべてでした。
開発初期:最初は順調だった
Pythonを書くのは初めてでしたが、C#やJavascriptなどである程度のコーディング経験はこの頃からあったので、開発自体はまずまず順調でした。
ASP.NETでMVCアーキテクチャを経験していたこともあったので、構築全体としても最初の内はさしたる苦労はなかったと記憶しています。
開発中期~後期:徐々にヤバくなってくる。コードの品質が上がらない。
開発が進み、システム規模もある程度のサイズになってきましたが、この頃からちょっとこれキツイかも・・・と思い始めた点がありました。
それは特にバッチ処理の品質がなかなか上がってこないことです。このバッチ処理は、繰り返し処理も含む緻密な計算を含んでおり、大体3,000~5,000行くらいのコードだったと思います。
Pythonはご存じの通り動的型付け言語のため、変数の型をうっかり間違えてもビルドするまでエラーに気づかず、その行に処理が至ったときにはじめて不具合が認識されます。
これが数千行に及び条件分岐も増えてくるとさすがにすべての行を検証するのは困難となってきます。
また、その他UIなどのバックグラウンド処理でも、静的言語で組んでいたらもっとスムーズにミスを検出できるのになぁ・・・という場面が頻発します。
それでも何とか開発と検証を進め、α版をリリースするに至りました。
社内にα版リリース:来る日も来る日もクラッシュ報告
もう少ししっかり時間を取ってテストコードを拡充すればまだマシだったと思うのですが、手元のテストデータで問題がなくなった段階で社内にいったんリリースしました。
とにかく使ってもらわないことには改良も後手になるので、この時点でリリースしたこと自体は、リスク管理の面からも良かったと感じます。(結果的に方針転換にも結び付いたので)
ところがリリース直後から、とにかく毎日のようにエラー報告が届きはじめます。
既にお察しの方も多いかと思いますが、出るわ出るわAttributeError(この型にそんな属性はないよ!)や条件分岐のミス。
このシステムでは入力に対してバッチを掛ける要件だったので、未知のデータをインポートされたときのデータ型が想定外のものになり、クラッシュを大量に起こしました。
また条件分岐ミスは、Pythonの(個人的に困った)特徴の一つ、if文の条件式がBool型ではなくてもエラーにならないという性質に基づいたものでした。
なので例えば、
Python
item = 'fuga'
if item:
print('hogehoge')
なんてマヌケなコードを書いても何ら警告もエラーもなく走ってしまうのです。
こんな単純な例ならいいのですが、数千行積もったコードの中にこんなミスが入っていたら、なかなか気づかないですし、テストコードで不具合を認識しても原因究明にかなり時間を要することが想定されます。
1週間くらい対応を続けたのですが、「これはさすがにこのまま走り続けるのは危険だ」と寒気を感じました。
今ある機能が問題なくなってきたとしても、その後の追加機能や改修のたびにこのような状態になっては(あるいはなる危険性があっては)業務としてとても立ちゆきません。
開発継続を一旦断念。静的型付け言語に手動翻訳して再開発することに。
このような状況を踏まえ、ここまで構築してきたPython+Djangoのコードを捨てる決心をしました。
1人開発ということもあり動的型付け言語のメリットも薄い中、静的型付け言語への移行は必須と感じたのです。
自分の技術的手札の中で、静的型付け言語でWebアプリを作れるのはC# + ASP.NETのみです。このFWに、これまで書いたPythonコードを翻訳していく作業を開始しました。Pythonの開発に要したのが6週間、この翻訳作業に要したのが2週間という作業感でした。
C#移行後は本当に快適でした。デプロイ後に型エラーが出ないだけでこんなにも気が楽なものか、と感動したのを今でも覚えています。
顛末:社内プロジェクトだったので影響は限定的でしたが
書き換え作業が追加で発生してしまいましたが、翻訳の追加作業が発生したくらいで全体として大きな影響は出さずに済みました。(α版を触っていただいた方には大変申し訳なかったですが・・・)
ただそれ以上に、自分の中で動的型付け言語をエンタープライズ規模で採用する危険性を肌で感じ取った経験でした。
「Pythonや動的型付けはダメ」ではないということ
Python/動的型付けはダメなのではなく、言語の性質に応じた役割があるということです。
このような軽量言語は、日ごろのタスク処理や小規模の開発では非常に高いパフォーマンスを発揮します。
私自身も、日ごろの様々な面倒作業をPythonで自動化しており、私のデスクトップにはPythonを起動するためのbatファイルを色々並べているヘヴィユーザーでもあります。
ただ、今回のケースのように、実装した処理が長期間保持され、多数のユーザーに使用されるようなコードには向いていないということだと思います。
この点を身をもって学んでしまった今回のケースは、個人的には今でも思い出深い財産になっています。
複雑なビジネスロジック計算がなければDjangoでもよかった
Djangoについては大規模開発に向いているという意見もありますが、今回のケースのようにある程度複雑な計算(Numpyで処理できるような科学計算ではなく独自のビジネスロジック)を伴う場合は危険である可能性があります。
CRUD+αくらいの規模感であれば効率的に開発出来て素晴らしいFWだとは思うのですが、要件の中にネックとなりそうな処理がないかどうかは慎重に検討する必要があるでしょう。
科学計算や機械学習を含むプロジェクトにおいてはDjangoは強力なFW
PythonはNumpyやPandasをはじめとする科学計算や機械学習を利用するAPIにおいて強みを持つ言語です。
こういったツール類を直接的にWebアプリやWeb APIに組み込めるという点で、Djangoは優れていると言えます。技術選定において、この様な要件があれば積極的に採用する理由になるでしょう。
記事筆者へのお問い合わせ、仕事のご依頼
当社では、IT活用をはじめ、業務効率化やM&A、管理会計など幅広い分野でコンサルティング事業・IT開発事業を行っております。
この記事をご覧になり、もし相談してみたい点などがあれば、ぜひ問い合わせフォームまでご連絡ください。
皆様のご投稿をお待ちしております。