如何使 python 脚本自行更改?
How can I make a python script change itself?
如何使 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
这有可能吗?该脚本可能使用外部资源;然而,一切都应该通过 运行ning 一个 run.py
-file.
编辑:
可能还不够清楚,但脚本应该更新自己,而不是任何其他文件。当然,一旦您允许脚本旁边有一个简单的配置文件,这个任务就很简单了。
举个例子(每次运行改变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:]))
创建一个文件 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
在程序的第一个 运行 中,a
将是 0
,并且它会将文件更改为包含 1
。在随后的 运行 秒中,a
将继续每次递增 1。
您所要求的将要求您在 {sys} 级别操作文件;基本上,你会读入当前文件,修改它,覆盖它,然后重新加载当前模块。我只是简单地玩了一下,因为我很好奇,但我 运行 陷入了文件锁定和文件权限问题。这些 可能 是可以解决的,但我怀疑这并不是您真正想要的。
首先:认识到在代码和数据之间保持分离通常是个好主意。这也有例外,但对于大多数目的,您需要让程序中可以在运行时更改的部分从文件中读取它们的配置,并将更改写入同一文件。
其次:同理,大多数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
如何使 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
这有可能吗?该脚本可能使用外部资源;然而,一切都应该通过 运行ning 一个 run.py
-file.
编辑: 可能还不够清楚,但脚本应该更新自己,而不是任何其他文件。当然,一旦您允许脚本旁边有一个简单的配置文件,这个任务就很简单了。
举个例子(每次运行改变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:]))
创建一个文件 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
在程序的第一个 运行 中,a
将是 0
,并且它会将文件更改为包含 1
。在随后的 运行 秒中,a
将继续每次递增 1。
您所要求的将要求您在 {sys} 级别操作文件;基本上,你会读入当前文件,修改它,覆盖它,然后重新加载当前模块。我只是简单地玩了一下,因为我很好奇,但我 运行 陷入了文件锁定和文件权限问题。这些 可能 是可以解决的,但我怀疑这并不是您真正想要的。
首先:认识到在代码和数据之间保持分离通常是个好主意。这也有例外,但对于大多数目的,您需要让程序中可以在运行时更改的部分从文件中读取它们的配置,并将更改写入同一文件。
其次:同理,大多数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