2024.12.10
“放置系”なのにサイバー攻撃を監視・検知、「統合ログ管理ツール」とは 最先端のログ管理体制を実現する方法
リンクをコピー
記事をブックマーク
Atsushi Odagiri氏:この時間はビギナーセッションで、内容はPythonでの開発を効率的に進めるためのツール設定です。
まず「ツール設定」という趣旨の説明と、あとは今日説明するツールがflake8、black、mypy、pytest、toxなどがあります。そしてそれぞれを使うためにエディタ設定をするという流れになっております。
先に自己紹介させていただきますと、私、Atsushi Odagiriという名前を縮めて、aodagという名前でネット上では活動しております。
今、株式会社オープンコレクターというところで仕事をしております。よく「どんなサービスを作っていらっしゃるんですか?」とキラキラした目で聞かれますけど、受託の会社ですので、寂しい思いをするのであまりそういう質問をしないでください。
あとpylonsproject.jpという、Webアプリケーションフレームワークを作っているプロジェクトの日本ドメインを保持してメンテをしておりますが、たいがい毎年3,000円払うだけみたいな活動をしております。
今日のお題は、開発を効率的に進めるためのツールを知りましょうというものです。「効率的に進める」というのは何なのかというと、つまらないミスをしないようにしましょうということです。効率的と聞いて、「よし、俺の能力がすげえパワーアップするぜ!」みたいな、そんな話はまったくありません。皆さんがやっているコーディングがだいたい60パーセントの効率だとしたら、ツールを使って80パーセントに上げましょうという渋い話です。
「つまらないミスをしないようにがんばる」と言っても、「ミスするな!」と言われて、「いや、それはミスはしたくないよ」とがんばるんですが、やっぱりがんばるだけではミスはいつか出てくる。でも機械であれば何度そういうチェックをしても疲れないので、ツールを使うことでつまらないミスを減らして、手戻りを少なく効率的に開発を進めましょうということです。
そのための準備ですが、みなさんは実際今から「ちゃんと手を動かしてやるぜ!」という人ですか?
(会場挙手)
いますね。がんばってください。いつでもvenvで作業しましょう。たぶん作ってあると思うので飛ばします。
ではまずflake8から説明します。flake8というのは静的チェックツールです。「静的」というのはどういうことかというと、コードを実行せずにチェックしてくれるツールです。
ユニットテストとかは実際に動かすことでエラーを発見するツールですが、静的チェックツールというのは、コードの状況を見て「これバグっぽくない?」というところをチェックしてくれるツールです。
「ユニットテストを使えばいいんじゃないか」という話もありますが、なぜ静的チェックツールを使うかというと、ユニットテストで実行した場合のエラーというのはもうバグなんです。その前に静的チェックによってバグにつながるコードをすぐに判別することができます。
あと、レビュアーに「あれ、この変数使ってなくね?」とか「このimportって意味あるの?」とか細かいチェックを受けて直すより、機械に言われて直したほうが気分はいいです。あと、レビュアーももっと深いレビューをしたいのに、そういう細かいチェックからしないといけないのは気分があまりよろしくないです。お互いの精神衛生のために静的チェックツールを使って、「なんかやべえな」というコードは事前にチェックしておきましょう。
flake8のインストール方法は簡単で、「pip install flake8」です。
この場でみなさんが一気にインストールをするとネットワークがどうなるかわからないです。もし失敗して、隣の人がやっていたら、「お願いします」と言って見せてもらって、「ああ、なるほど」と思ってください。
flake8には.flake8とかsetup.cfg、tox.iniといった設定ファイルがたくさんあります。でもflake8のほかにもmypyとかblackとかいろんなツールがあるのに、それらの独自なファイルを全部使っていると、トップディレクトリにファイルが散らばって、どこに書いてあるかわからなくなります。たいていのツールはsetup.cfgかtox.iniの2つに設定を書けるようになっているので、そちらに書くのがいいでしょう。
どんな設定ファイルになるかというと、flake8というセクションがあって、たいていの場合その中に書くのはmax-line-lengthを伸ばすという設定と、あとはignoreしたい、「ここはチェックしなくていいよ」というものを入れるのがよくある設定です。
ではflake8の実行例です。さあみなさんこれを見てみましょう。
イラッとしますよね? 「さすがにこんなバカなコードを書く人なんていないだろ」と思うかもしれません。例えばaddが上にも下にもあります。「さあ、このfの中でaddはどっちが呼ばれるの?」となるでしょう。
これは短いので、みなさんパッと見て「こんなんアホやん」みたいな感じになるんですけど、1,000行、2,000行の中でこういう状況になると意外と気がつかないものです。例えばaddなんていう汎用的な名前はけっこう何箇所も書いてしまうものなんです。こういうのを探し当てることができます。
ちなみに、addが2つあるというので、「じゃあ下のaddのほうが正しいじゃん?」と思うかもしれませんけど、flake8にチェックさせると、「F811 redefinition of~」 のところで、「addが再定義されているよ」と誰が見てもわかるようになっていますね。
次にもう1個下に「F841 local variable ‘c’ is〜」と書いてあるんですけど、「c作ってるけど入れてない、使ってない」というものです。これはかなりバグにつながるやつですよね。たぶん上のやつをどうにか修正しようとしたのに、マージミスでreturn a + b が残っちゃって、結局きれいにしたcを使ってないみたいなケアレスミスです。
これぐらいだったらすぐ見つかるんですけど、複雑なコードになると見つけるのは大変です。flake8は機械ですので、こういうのをちゃんと的確に見つけてくれます。ということで、それをちゃんとflake8を実行してこういうエラーがチェックできるかどうかをやってみましょう。
このエラーを修正するときれいなコードになります。
ここでまたflake8を実行すると、警告が出ない。ということがみなさんできたと思います。flake8はこういう感じで、ちょっとしたミスをチェックしてくれるツールです。
次にblackにいきます。blackというのはPEP8準拠のコードフォーマッターです。さて、ビギナーセッションとはいえ、PEP8がわからない人はいますか?
(会場挙手)
少しいますね。PEPはPython Enhancement Proposalと言って、Pythonのいろんな決めごとを作っているものですが、その8番目がPythonコードのフォーマッティングについての説明です。それに準拠してコードをきれいに整形してくれるツールがコードフォーマッターです。
blackは一番新しいコードフォーマッターです。昔からautopep8とかyapfとかいろいろあるんですけど、なぜblackが最近流行りになってきているのかというと、blackは設定がほとんどできないんです。
あとは、autopep8かyapfというのは、PEP8に従っているコードだったらそれはそのままにしてくれるんです。だから、「自分的にはここの引数は全部縦に並べておきたい」とやっておいたときに、autopep8とかは縦に並べたままにしてくれるのですが、blackは行の長さに引っかからないかぎり問答無用で全部横に並べます。
「俺がきれいに並べたコードが全部blackによって破壊される!」みたいなことを言ってくる人がけっこういるんですが、もうそういうので悩むのはやめましょう。blackがそう言うんだからもう全部blackでやる。blackは何回やっても同じ結果になります。「だって、事前に整形するんだったら、またその事前の整形の流派とかが出てくるわけじゃん?」という感じですね。
あと、ほとんど設定できないということで、例えば「ここの縦に並べるのだけはちょっとこののプロジェクトでは変えよう」というのが発生するのを防げます。プロジェクトごとにちょろちょろ変えたような微妙に違うautopep8の設定があったりするわけですけど、そういうのはもうやめて、「もうblackで全部いきましょう」ということです。
ただし、blackはPython3.6以上でしか使えないので、3.5の人は早く3.6に上げましょう。
なぜフォーマッターを使うのかという話です。「PEP8で決まっているんだからフォーマットしようよ」という話はもちろんあるのですが、なぜフォーマットをするのかというと、まず圧倒的に読みやすいからです。あと、フォーマットされたコードの中で変なことをしていると、だいたいすぐわかります。
「ifダダダダダダダ:」みたいな超読みにくいコード、「これは絶対何かがおかしい」と比較的すぐわかるのがフォーマッティングのいいところです。フォーマッティングをすると、何か変なことをしていたら変に見えるんです。
ではこのblackをどうやって使うかというと、「pip install black」とすると、blackがインストールされて使えるようになります。
一応blackは設定ファイルpyproject.tomlがございますが、私としてはデフォルトでいっていただきたいです。ただ行の長さをちょっと変えたいという人はいるかもしれないです。120とか200とか、「もう2,000でもいいよ」とか。
blackはデフォルトが88という超中途半端な長さになっているので、そこが気に食わない人は設定してもいいかもしれないと思います。ただ、プロジェクトごとにいろいろ変わると鬱陶しいので、「もうプロジェクト全体でデフォルトでいこう」ということなら、それはそれでいいと思います。
blackには実際にフォーマットしてしまう以外の使い方があります。まず使ってほしいのが、blackでコードをフォーマットをしたら、この--checkオプションを使ってblackにフォーマット済みになっているかどうか判定できるというものです。例えばこれをCIとかでチェックして、「ちゃんとフォーマットしていないとマージされない」みたいなガチ仕様でいくのもよいでしょう。
あと、--diffを使うとどう変換されるのかが出てきます。CI上で引っかかってどうやって直すのかがすぐわからないとき、--diffも一緒に出してあげることですぐに「あっ、ここ直さなきゃ」とわかるようにできます。なので、blackを使うときは、自分だけフォーマットが引けることに加え、--checkとか--diffとかを使ってみんなで守っていきましょうという、こういうコマンドラインのオプションも使っていただきたいと思います。
ではblackの実行例です。これは正しいコードですし、たぶんPEP8には違反していないはずです。なのでautopep8とかyapfとかを使うと、これはこのまま残るはずです。
でも、blackはそんなことはお許しにならないので、ちゃんと横に並べます。これはblack --diffを使いました。black --diffを使うと、「このコードはこうやって整形するよ」というdiffが出てきます。--diffオプションをつけなければ実際この内容に整形してくれます。
なので、みなさんも試す場合にはこういう無茶なフォーマッティングを書いてblackをかけることで、超きれいになるというのを確認していただきたいなと思います。
次にmypyです。flake8はおそらくもう導入済みの方はけっこういるかと思います。flake8を個人的に使っている人?
(会場挙手)
プロジェクト全体でも使っている人?
(会場挙手)
CI上でチェックまでやっている人?
(会場挙手)
けっこう少なくなりましたですね。mypyを使っている人?
(会場挙手)
おっ。プロジェクトでmypyを使っている人?
(会場挙手)
ignore_missing_importsなしでmypyを使っている人?
(挙手なし)
さすがにいないね。mypyは、最近話題になってきているtype hintというのをチェックするためのツールです。分類上はflake8と同じ静的チェックツールなので、mypyを使って型チェックをすることができますが、その型チェックで実行時に影響を与えることはないです。
「なんでtype hintを入れるのか?」と。「だってPythonはスクリプトで簡単に書けるのに、そこにわざわざ型を書くとか超面倒じゃん」みたいな話になると思うのですが、「でもどっちにしろお前たちはドキュメントやdocstringのところに『str』とか型を書いているじゃないか」と。書いてない人?
(挙手なし)
うん、大丈夫だね。ドキュメントやコメントで書くより、ソースコードの中に実際に型として書いてあったほうがより厳密になります。ただし書いていないからといってそのコードが動かないわけではないです。基本的には「このコードはこういう型が来るものとしている」という意思表明として書きます。
あと、ちゃんとtype hintを入れると、補完するエディタがきれいに補完をしてくれます。ただしtype hintが間違っている場合はほかも間違ってしまうので、ちゃんと正しいtype hintが書いてあるかをmypyでチェックすることによって、こういったエディタの補完も間違いがないように出てきます。
「mypyをちょっと入れたいな」という感じでobjectと書いている人がたくさんいるのですが、そこはAnyです。objectは「object」という型になってしまいます。そこには追加のプロパティを代入することもできないし、object以外のメソッドを呼ぶこともできないので、objectとAnyを間違いないようにしましょう。
mypyのインストールは、これまた簡単に「pip install mypy」で入ります。
そして、mypyの設定ファイルにはmypy.iniとかあるんですけど、やっぱりsetup.cfgに全部まとめておくほうがおすすめです。増えますからね。
さっきignore_missing_importsを使っているかと聞いたのですが、これは今のところほとんど必須のオプションになります。なぜかというと、使っているライブラリも全部 mypyチェックにいってしまうので、使おうとしているライブラリがmypy、type hintに対応しておかないと、そこでもうエラーになってしまいます。一応「なきゃないでしょうがない」です。過渡期で、おそらくこの過渡期が終わることはないでしょう。おそらくずっとこのオプションは必要になるに違いありません。そういう設定をするために「ignore_missing_imports = 1」 と、setup.cfgのmypyセクションに書いておきましょう。
ではmypyを使うと何がわかるのか? 先ほども出てきましたね。addをするときにNoneだったらちゃんと0に変えて足し算するというものです。でもちょっと間違えていて、 return a + bというのも先ほどのままですが、何が違うかというと、aはOptional[int]というタイピングをしてあります。bはintというタイピングをしてあります。
これでチェックをすると、fからaddを呼ぶときにOptionalのほうはNoneを渡すことができます。bはintと書いてあるので、ここのintはNoneを渡せないのでもう0と書いてあります。
なので、呼び出し方は大丈夫です。ただし、がんばってcに0を入れているのに、そのあとa + bと書いてあって、「なんかおかしいよね?」というのがありました。
これをmypyでチェックすると、「Unsupported operand types for + 〜」と書いてあるのですが、これはa + bのところで、Optional[int]+ intはできないとmypyが警告しています。
なぜかというと、Optional[int]にはNoneが来るかもしれないので、これではNone+ 1というふうにはできないと言っているのです。実はその上の「c = ~」というところで、ちゃんと0になるように作ってあるのに、これを使うのを忘れるという、flake8のときと同じミスを犯しています。mypyを使ってもだいたい同じようなことはチェックができます。
こういう警告をされていますので、先ほどのコードを写していた人は、ここのOptional[int]というところと、bにも「int」というのをつけてあげてからmypyを実行して、ちゃんとチェックできるかやってみていただければと思います。
先ほどのやつは、c +bに変えればいいですね。こう直してあげるとmypyは警告してこなくなります。
関連タグ:
2024.12.20
日本の約10倍がん患者が殺到し、病院はキャパオーバー ジャパンハートが描く医療の未来と、カンボジアに新病院を作る理由
2024.12.19
12万通りの「資格の組み合わせ」の中で厳選された60の項目 532の資格を持つ林雄次氏の新刊『資格のかけ算』の見所
2024.12.16
32歳で成績最下位から1年でトップ営業になれた理由 売るテクニックよりも大事な「あり方」
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
PR | 2024.12.20
モンスター化したExcelが、ある日突然崩壊 昭和のガス工事会社を生まれ変わらせた、起死回生のノーコード活用術
2024.12.12
会議で発言しやすくなる「心理的安全性」を高めるには ファシリテーションがうまい人の3つの条件
2024.12.18
「社長以外みんな儲かる給与設計」にした理由 経営者たちが語る、優秀な人材集め・会社を発展させるためのヒント
2024.12.17
面接で「後輩を指導できなさそう」と思われる人の伝え方 歳を重ねるほど重視される経験の「ノウハウ化」
2024.12.13
ファシリテーターは「しゃべらないほうがいい」理由 入山章栄氏が語る、心理的安全性の高い場を作るポイント
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
Climbers Startup JAPAN EXPO 2024 - 秋 -
2024.11.20 - 2024.11.21
『主体的なキャリア形成』を考える~資格のかけ算について〜
2024.12.07 - 2024.12.07
Startup CTO of the year 2024
2024.11.19 - 2024.11.19
社員の力を引き出す経営戦略〜ひとり一人が自ら成長する組織づくり〜
2024.11.20 - 2024.11.20
「確率思考」で未来を見通す 事業を成功に導く意思決定 ~エビデンス・ベースド・マーケティング思考の調査分析で事業に有効な予測手法とは~
2024.11.05 - 2024.11.05
メッセージを残していただければ幸いです