やりたいこと
今回のやりたいことは、表題の通りです。
(淡々と書きますので、ご容赦を...)
なぜやりたいの?
現在、「小さく関数を作ってつなぎ合わせて大きいものを作る」ということを意識して、コツコツと学習をしています。
インタラクティブモードで動作確認をしつつ、エディタ側のソースコードに反映させていくという流れで取り組んでいます。
さて、実際にソースコードの変更をしたので、起動中のpythonのコンソールから、変更の内容、動作確認をしたい...となったとき。
Railsだとconsoleで同じように確認していて、reload! とすると再読み込みしてくれるので、同じようなことがしたい...。
ただしフレームワークを使ったものではなく、単体のスクリプトなので、どうしたものかと調べていました。
とりあえずやってみたこと
こんなコードを用意します。
class Greeting:
def hello(self):
print("Hello World!")
def try_greeting(method_name='hello'):
greeting = Greeting()
if method_name is None:
method_name = 'hello'
eval('greeting.' + method_name)()
def main():
try_greeting()
if __name__== "__main__":
main()
まずは直接pythonコマンドにソースコードを渡して、簡単に動かしてみます。
$ python sample.py
Hello World!
つぎに -i オプションで、インタラクティブモードで呼び出して動かしてみます。
$ python -i sample.py
Hello World!
>>> main()
Hello World!
今度は、引数無しで起動します。
>>> import sample
>>> sample.main()
Hello World!
# このあと、エディタ側で print("こんにちは!")に書き換えてsave
# でも変わらない...
>>> sample.main()
Hello World!
# importlibを使って再読み込みさせます
>>> import importlib
>>> importlib.reload(sample)
<module 'sample' from '/Users/akiko/work/convert_qiita/sample.py'>
# こんどは反映されました
>>> sample.main()
こんにちは!
クラスも試します
同じインタラクティブモードのまま。
# 書き換えた状態でGreetingのインスタンスを作成
>>> g = sample.Greeting()
>>> g.hello()
こんにちは!!!!
# このあと、print("こんにちは!!! うまくできてますか?") に書き換え
>>> importlib.reload(sample)
<module 'sample' from '/Users/akiko/work/convert_qiita/sample.py'>
# 再読み込みをさせますが、すでにインスタンス化されているものは、メソッドは変更が反映されません
>>> g.hello()
こんにちは!!!!
# 追加で新しく作ったほうは、変更が反映されています
>>> g2 = sample.Greeting()
>>> g2.hello()
こんにちは!!! うまくできてますか?
まとめ
簡単ですが、うまくいきました。
ただし、上記で試したとおり、クラス利用の場合は挙動に注意。
また、再読み込みする前に生成されたオブジェクトや変数は、変更が適用されていませんので注意。
補足
少し前に、こういうメモを上げましたが、こちらの方法でいけそうかな?