web-dev-qa-db-ja.com

pythonスクリプト自体を変更するにはどうすればよいですか?

pythonスクリプト自体を変更するにはどうすればよいですか?

要約すると、pythonスクリプト(run.py)このような

a = 0
b = 1
print a + b
# do something here such that the first line of this script reads a = 1

次回スクリプトを実行すると、次のようになります。

a = 1
b = 1
print a + b
# do something here such that the first line of this script reads a = 2

これは何らかの方法で可能ですか?スクリプトは外部リソースを使用する場合があります。ただし、1つを実行するだけですべてが機能するはずですrun.py-ファイル。

編集:それは十分に明確ではなかったかもしれませんが、スクリプトは他のファイルではなく、それ自体を更新する必要があります。確かに、スクリプトの横にある単純な構成ファイルを許可すると、このタスクは簡単です。

回答:

実際、思ったよりずっと簡単です。 @khelwoodの提案は問題なく機能し、スクリプトを開いて独自のコンテンツを書き込むことはまったく問題ありません。 @Gerratのソリューションもうまく機能します。これは私がそれを持っている方法です:

# -*- coding: utf-8 -*-
a = 0
b = 1
print a + b

content = []
with open(__file__,"r") as f:
    for line in f:
        content.append(line)

with open(__file__,"w") as f:
    content[1] = "a = {n}\n".format(n=b)
    content[2] = "b = {n}\n".format(n=a+b)
    for i in range(len(content)):
        f.write(content[i])

例(実行するたびにaの値を変更する):

a = 0
b = 1
print a + b

with open(__file__, 'r') as f:
    lines = f.read().split('\n')
    val = int(lines[0].split(' = ')[-1])
    new_line = 'a = {}'.format(val+1)
    new_file = '\n'.join([new_line] + lines[1:])

with open(__file__, 'w') as f:
    f.write('\n'.join([new_line] + lines[1:]))
6
Gerrat

1行に1文字を含むファイルa.txtを作成します。

0

次に、スクリプトでそのファイルを開いて値を取得し、すぐに変更します。

with open('a.txt') as f:
    a = int(f.read())
with open('a.txt', 'w') as output:
    output.write(str(a+1))
b = 1
print a+b

プログラムの最初の実行時に、a0になり、1を含むようにファイルが変更されます。以降の実行では、aは毎回1ずつ増加し続けます。

0
TigerhawkT3

あなたが求めているのは、{sys}レベルでファイルを操作する必要があるでしょう。基本的には、現在のファイルを読み込んで変更し、上書きして、現在のモジュールをリロードします。興味があったので簡単にこれを試してみましたが、ファイルロックとファイルパーミッションの問題に遭遇しました。それらはおそらく解決可能ですが、これは本当にあなたがここで望んでいるものではないのではないかと思います。

まず、コードとデータを分離しておくことをお勧めします。これには例外がありますが、ほとんどの場合、実行時に変更できるプログラムの部分でファイルから構成を読み取り、同じファイルに変更を書き込む必要があります。

2番目:理想的には、ほとんどのpythonプロジェクトは構成に [〜#〜] yaml [〜#〜] を使用します

これは、yamlライブラリを使用して「config.yaml」というファイルから読み取り、プログラムが実行されるたびに「a」の値をインクリメントする簡単なスクリプトです。

#!/usr/bin/python
import yaml

config_vals = ""
with open("config.yaml", "r") as cr:
   config_vals = yaml.load(cr)

a = config_vals['a']
b = config_vals['b']
print a + b

config_vals['a'] = a + 1
with open("config.yaml", "w") as cw:
   yaml.dump(config_vals, cw, default_flow_style=True)

ランタイム出力は次のようになります。

$ ./run.py
3 
$ ./run.py
4
$ ./run.py
5 

初期のYAML構成ファイルは次のようになります。

a: 1
b: 2
0
Joe