自作の映画情報投稿ツールをスマホアプリとして作れないかとやってるんですが未知の領域の部分には困りごとが出てきます。
映画のタイトルや公開年をshellの引数で取るようにしているのですがスマホアプリで使うならそうはいきません。
専用に修正すればなんてことないのですがモジュールとして使うからにはそのまま使いたいところ。
元のコードを直せば...と言っているとキリがありませんのでコード内で収まらないか色々試したところ出来たのでメモしておきます。
引数用の属性を探せ
引数処理はargparseを使っています。
まずはテスト用のサンプルコード。
(movies) masashi@PC-ubuntu:~$ cat argtest.py import argparse parser = argparse.ArgumentParser() parser.add_argument('--year', type=int) args = parser.parse_args() def main(): if args.year: print('{}年宇宙の旅'.format(args.year)) else: print('2001年宇宙の旅') if __name__ == '__main__': main()
シェルから使うとこんな感じ。
(movies) masashi@PC-ubuntu:~$ python argtest.py 2001年宇宙の旅 (movies) masashi@PC-ubuntu:~$ python argtest.py -h usage: argtest.py [-h] [--year YEAR] optional arguments: -h, --help show this help message and exit --year YEAR (movies) masashi@PC-ubuntu:~$ python argtest.py --year 2022 2022年宇宙の旅
pythonシェルでテスト
バージョン。仮想環境内です。
(movies) masashi@PC-ubuntu:~$ python --version Python 3.8.10
プロンプト内でimportします。
>>> import argtest
困ったらdir。
>>> dir(argtest) ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'argparse', 'args', 'main', 'parser']
argsという属性があります。
これは引数処理で使ったぞ。
中身。
argsにアクセスしたら引数として書いたyearの変数がありますね。
これを変えればいけそうな感じ。
>>> argtest.args
Namespace(year=None)
今はNoneなので何も返ってきません。
>>> argtest.args.year >>>
値を入れてみます。
>>> argtest.args.year = 3000 >>> argtest.args Namespace(year=3000)
mainで実行。
>>> argtest.main()
3000年宇宙の旅
OK。変わりましたね。 再度関数化すればコード内でも使えそう。
実際のコードで試す
投稿した映画タイトルを呼んでみます。
自作モジュールのpathは追加済み。(呼び出し方法で少しはまりましたが割愛)
>>> import movietweet.gettw >>> >>> movietweet.gettw.args Namespace(year=None)
とりあえず直近10件だけ出すよう関数作ります。
エラーハンドリングは後で考えます。
>>> def gettitle(y): ... movietweet.gettw.year = y ... movies = movietweet.gettw.main() ... for movie in movies[:10]: ... print(movie['posted_date'], movie['title']) ... >>>
実行。
>>> gettitle(2022) 2022-06-11 23:50:32 The Suicide Squad 2022-06-05 23:41:30 Spenser Confidential 2022-06-05 00:30:57 Carlito's Way 2022-05-29 22:53:19 Uncorked 2022-05-28 23:27:57 Ghost Dog: The Way of the Samurai 2022-05-22 22:54:41 Kong: Skull Island 2022-05-22 10:49:03 The Mummy Returns 2022-05-15 23:14:56 Superlopez 2022-05-15 10:15:04 The Interpreter 2022-05-08 21:35:03 Jefe
OK!うまいこと動きました。
この方法を組み込みたいと思います。
ちなみに視聴したこの10件だとUncorked(邦題: ワインは期待と現実の味)が一番面白かったかな。
本件で使ったリポジトリはこちらです。
おまけ
シェルからの引数はimportだとできないんじゃないかと思っていて、初めはrunpyというモジュールを使おうと思っていました。 属性へのアクセスは同じです。
こっちはファイルをそのまま読み込むみたいな感じでしょうか。
辞書型で各属性が格納されるようです。
>>> import runpy >>> runpy.run_module('argtest')['__name__'] 'argtest'
argsへのアクセス結果は同じですね。
>>> runpy.run_module('argtest')['args'] Namespace(year=None)
しかしそのまま入れてもダメ。
runpyモジュールを都度実行しているからでしょうか。
>>> runpy.run_module('argtest')['args'] = 3000 >>> runpy.run_module('argtest')['main']() 2001年宇宙の旅
変数に格納したら値が記憶できました。
>>> title = runpy.run_module('argtest') >>> title['args'].year = 3000 >>> title['main']() 3000年宇宙の旅
これで同結果が得られました。
しかしimportで出来ることがわかった以上こちらは使わなくても大丈夫でしょう。