All Articles
    Search by

    subprocessライブラリの使い方って結局何が正解なん

    pythonライブラリの使い方が分からなくなることがある

    pythonライブラリにはド定番のライブラリがいくつもあるが、それらの仕様は結構忘れがち。

    たとえばcsvDictWriterクラス。引数がファイルオブジェクトなのかそれともパスを文字列で与えるのか、刹那の思考をはさんだ後にwith open()などと書き始める。

    csv.DictWriterクラスならまだ良いが、やり方が複数通り存在する場合になるともうカオスだ。urllib.requestrequestsのどっち使うんだとか、はたまたurllib3はなんなんだとか。。そんな「結局何が正解なん」案件でsubprocessの使い方についてちょっと思うところがあった。

    subprocessライブラリの使い方

    色々やりたいときはPopenクラスを使う、簡単なユーズケースならrunメソッドを使う、という認識でいたので、基本的に何も考えずPopenクラスを毎回使っていた。

    こんな感じ。

    from subprocess import Popen
    
    ps = Popen(['ls', '-lah'])
    ps.wait()

    Popen.wait()するタイミングをずらすことで非同期処理的にマルチプロセス化することもあるため、個人的にはシェルスクリプトとしてpythonを使う際には欠かせないやつ🤔

    stdoutを使おうとするとちょい面倒

    標準出力を取得しようとするとsubprocess.PIPEが必要になるのでちょいめんどくさい。バイト文字列で選ってくるところがなおさら😅

    from subprocess import Popen, PIPE
    
    ps = Popen(['echo', 'hello'], stdout=PIPE)
    s_out = ps.stdout.readlines()
    print([s.decode("utf-8") for s in s_out])
    ['hello\n']

    ググったらsubprocess.runの方が楽らしいと知る

    こちらのQiita記事を拝読すると、「suborocess.runを使うのが良いとされている」とか「capture_outputを使ってもできる」というのを聞いて👀から🐟!

    import subprocess
    
    ps = subprocess.run(['echo', 'hello'], capture_output=True, text=True)
    s_out = ps.stdout
    print(s_out)
    hello

    —はぁ・・・勉強不足でした。。すみません。。と思いつつdocumentを見ると確かに以下のようにrunメソッドが推奨されていた。1

    サブプロセスを起動するために推奨される方法は、すべての用法を扱える run() 関数を使用することです。より高度な用法では下層の Popen インターフェースを直接使用することもできます。

    また、capture_outputオプションはpython3.7で実装されたらしい。なるほど比較的新しいけど、少なくともセキュリティサポートされているバージョンをきちんと追ってる人なら間違えてはいけないポイントだろう。

    みんなちゃんと情報フォローしてるのか?と気になって調べてみた

    結論、Qiita記事はちょっと危険だなと思った。自分も似たようなものだが・・・

    やばいパターン①推奨されていない書き方を解説している

    shell=Trueを使えば簡単にパイプが使えるので、便利なことは便利。しかし、任意のコードを実行させられる可能性があるので、ウェブフレームワークなどで使うのは御法度というのが有名。 これを説明せずに「shell=Trueの方が初心者にはオススメ」などと平然と書かれているケースがあった。

    ちょっと気になったパターン②capture_outputオプションの言及がない

    先に言っておくが、個人ブログは高確率でこれに言及している。最初の投稿時に言及が無くとも、ほぼ全員が追記していた。すごい😲きっと多分自分のコンテンツに責任を持っているのだろう。自分もそうならねば。

    Popen.PIPEの方法はQiita記事だけをみていたらゴールドスタンダードに見えるだろう。現に自分がそうだった。

    やっぱ、公式ドキュメントはちゃんと読んだ方が良いわ

    正直自分はpythonドキュメントきちんと読んでこなかった。だってフォントとかレイアウトとかのせいか、読みにくいんだもん。

    しかし、細かい推奨レベルや後で追加されたオプションなど、知らないと恥かく内容も多いと感じた。

    コツコツpythonドキュメントをちゃんと読み直してみるのもいい学習方法かもしれない。


    1. これを推奨ととるかは読解力次第な気もする

    Published Sep 12, 2022

    © 2020-2024 Hiroyuki Odake