pythonライブラリの使い方が分からなくなることがある
pythonライブラリにはド定番のライブラリがいくつもあるが、それらの仕様は結構忘れがち。
たとえばcsvのDictWriterクラス。引数がファイルオブジェクトなのかそれともパスを文字列で与えるのか、刹那の思考をはさんだ後にwith open()などと書き始める。
csv.DictWriterクラスならまだ良いが、やり方が複数通り存在する場合になるともうカオスだ。urllib.requestとrequestsのどっち使うんだとか、はたまたurllib3はなんなんだとか。。そんな「結局何が正解なん」案件でsubprocessの使い方についてちょっと思うところがあった。
subprocessライブラリの使い方
色々やりたいときはPopenクラスを使う、簡単なユーズケースならrunメソッドを使う、という認識でいたので、基本的に何も考えずPopenクラスを毎回使っていた。
こんな感じ。
|
|
Popen.wait()するタイミングをずらすことで非同期処理的にマルチプロセス化することもあるため、個人的にはシェルスクリプトとしてpythonを使う際には欠かせないやつ🤔
stdoutを使おうとするとちょい面倒
標準出力を取得しようとするとsubprocess.PIPEが必要になるのでちょいめんどくさい。バイト文字列で選ってくるところがなおさら😅
|
|
['hello\n']
ググったらsubprocess.runの方が楽らしいと知る
こちらのQiita記事を拝読すると、「suborocess.runを使うのが良いとされている」とか「capture_outputを使ってもできる」というのを聞いて👀から🐟!
|
|
hello
–はぁ・・・勉強不足でした。。すみません。。と思いつつdocumentを見ると確かに以下のようにrunメソッドが推奨されていた。1
サブプロセスを起動するために推奨される方法は、すべての用法を扱える run() 関数を使用することです。より高度な用法では下層の Popen インターフェースを直接使用することもできます。
また、capture_outputオプションはpython3.7で実装されたらしい。なるほど比較的新しいけど、少なくともセキュリティサポートされているバージョンをきちんと追ってる人なら間違えてはいけないポイントだろう。
みんなちゃんと情報フォローしてるのか?と気になって調べてみた
結論、Qiita記事はちょっと危険だなと思った。自分も似たようなものだが・・・
やばいパターン①推奨されていない書き方を解説している
shell=Trueを使えば簡単にパイプが使えるので、便利なことは便利。しかし、任意のコードを実行させられる可能性があるので、ウェブフレームワークなどで使うのは御法度というのが有名。
これを説明せずに「shell=Trueの方が初心者にはオススメ」などと平然と書かれているケースがあった。
ちょっと気になったパターン②capture_outputオプションの言及がない
先に言っておくが、個人ブログは高確率でこれに言及している。最初の投稿時に言及が無くとも、ほぼ全員が追記していた。すごい😲きっと多分自分のコンテンツに責任を持っているのだろう。自分もそうならねば。
Popen.PIPEの方法はQiita記事だけをみていたらゴールドスタンダードに見えるだろう。現に自分がそうだった。
やっぱ、公式ドキュメントはちゃんと読んだ方が良いわ
正直自分はpythonドキュメントきちんと読んでこなかった。だってフォントとかレイアウトとかのせいか、読みにくいんだもん。
しかし、細かい推奨レベルや後で追加されたオプションなど、知らないと恥かく内容も多いと感じた。
コツコツpythonドキュメントをちゃんと読み直してみるのもいい学習方法かもしれない。
-
これを推奨ととるかは読解力次第な気もする ↩︎