从另一个Python脚本更改Python脚本参数
我有一个主脚本,我想从中制作两个临时副本,每个副本都有细微的变化 main.py可以如下所示:从另一个Python脚本更改Python脚本参数,python,regex,Python,Regex,我有一个主脚本,我想从中制作两个临时副本,每个副本都有细微的变化 main.py可以如下所示: def replace_parameter_value_if_found(string, parameter, new_value): return new_string = re.sub("([\'\"]?"+parameter+"[\'\"]?\s*[=:]\s*)[\.\w]*", "\1"+new_value, string) 将NumPy作为np导入 导入模块 进口栏 ... f
def replace_parameter_value_if_found(string, parameter, new_value):
return new_string = re.sub("([\'\"]?"+parameter+"[\'\"]?\s*[=:]\s*)[\.\w]*", "\1"+new_value, string)
将NumPy作为np导入
导入模块
进口栏
...
foo=barlabel='C2H4',点=1,0
原子='H4'
template=读取'template.t'
大小=模板长度
n=4
α=0.5
批次大小=256//n*alpha
dct={
'1': [1, 2],
'6': [3, 4],
}
kwargs={
“dict”:dct,
“大小”:大小,
“比例”:大小[0]/10,
}
...
模块图、kwargs、foo
module.run
在另一个名为parameter_search.py的脚本中,我通过运行main.py中的每一行来复制并更改参数,搜索应该更改的内容
如果找到变量,一个regex命令会分割行,然后更改浮点值。我不是regex的高手,所以这可能需要一些工作:
进口稀土
导入文件输入
从shutil导入操作系统导入复制文件
def是_numvar:
尝试:
浮动变量
返回真值
除值错误外:
返回错误
def replacefilename,变量expr,新变量:
发现=错误
对于fileinput.inputfilename中的行,inplace=1:
如果var_expr在同一行:
如果未找到:
找到=真
lst=re.split'=|::|,',行
对于i,枚举LST中的字符:
如果是努姆查尔:
lst[i]=strnew\u val
行=.joinlst
其他:
raise NameErrorf'{var_expr}ambigous'
打印行,结束=
如果未找到:
在{filename}中找不到raise NameErrorf“{var_expr}”
N=[10,20]
α=[0.4,0.6,0.8]
foo=[baralpha=1,baz]
对于n中的n:
对于阿尔法中的a:
对于foo中的i,f:
newfile='main'
newfile+=f''n{n}'
newfile+=f''u a{a}'
newfile+=f''u f{i}'
newfile+='.py'
复制文件'main.py',新文件
replacenewfile,“n=”,n
替换新文件“alpha=”,使用
替换新文件'foo=',f
这提供了不错的结果,但如果多个变量在同一行上,例如barlabel='C2H4',point=1,0,或者变量是dict的一部分,例如kwargs,参数是字符串、函数或其他奇怪的变量,则会出现问题
是否有可能做出更通用的替换之类的东西,或者以其他方式使这成为可能 好吧,让我在这里做一些假设: 参数赋值在.py脚本中只发生一次,也是参数名的第一次出现。 有两种方法来声明一个参数:作为单个变量PAR=值或在字典中{PAR:}值为单引号或双引号。 然后,您可以使用re.sub函数直接替换分配的值,使用所谓的捕获组: 返回通过替换 替换repl的字符串中的模式。如果找不到模式, 字符串返回时保持不变。repl可以是字符串或函数;如果 它是一个字符串,其中的任何反斜杠转义都将被处理。也就是说,\n 已转换为单个换行符,\r已转换为 回车,等等。ASCII字母的未知转义是 保留供将来使用,并作为错误处理。其他不明逃逸 像\&这样的词就不用管了。将替换反向引用,例如\6 子串与模式中的第6组匹配 资料来源: 因此,为给定参数名设置新值的函数可能如下所示:
def replace_parameter_value_if_found(string, parameter, new_value):
return new_string = re.sub("([\'\"]?"+parameter+"[\'\"]?\s*[=:]\s*)[\.\w]*", "\1"+new_value, string)
现在,让我们将其分解:
"([\'\"]?"+parameter+"[\'\"]?\s*[=:]\s*)[.\w]*"
包含在中的内容称为捕获组-它可以是
稍后参考。
[]中包含的内容与反斜杠中的任何字符匹配,用作转义字符
? 一个量词是匹配零个事件还是匹配一个立即成功的事件
*量词是否匹配它立即成功的任何数量的事件,包括零
任何文本字符串都与该字符串匹配
\s和\w分别匹配任何空格和任何单词字符a-z0-9
因此,假设参数为'alpha',正则表达式模式变为
"([\'\"]?alpha[\'\"]?\s*[=:]\s*)[\.\w]*"
读起来是这样的:
def replace_parameter_value_if_found(string, parameter, new_value):
return new_string = re.sub("([\'\"]?"+parameter+"[\'\"]?\s*[=:]\s*)[\.\w]*", "\1"+new_value, string)
开放捕获组1
匹配单个“或”都不匹配,因为?
匹配文字alpha
匹配单个“或两者都不匹配”
匹配任意数量的空白字符
匹配单个=或:
关闭捕获组1它现在包含alpha=或“alpha”:或它的一些变体
匹配任意数量的单词字符或句点这是我们将要替换的
然后,所有这些将替换为捕获组1中的内容,然后是新值,因此:
"\1"+new_value
字符串可以是.py脚本的全部,也请记住,传递给函数的是字符串,它们可以是您想要的任何内容
希望这能有所帮助。我建议您学习更多关于正则表达式的知识,使用它们可以很好地解决这个问题
. 你可以在这个网站上测试它,直到你的正则表达式匹配你想要的一切。我想问一下,为什么你想修改脚本本身,而不是将值作为参数传递给脚本中的函数?我可能应该更深入地研究正则表达式,我只是不太理解它们,这不是唯一的问题。通常我会自己传递参数,但实际上我有很多主文件-它们都在使用强化学习做一些不同的事情我理解,首先列出每个可能的参数格式,然后我可以帮助您构造和解释正则表达式。为了澄清,也许需要编辑来询问以下问题:如果我想将一个字符串更改为另一个foo='bar'->foo='not'u bar',我是否应该将正则表达式修改为[\'\]?+参数+[\'\]?\s*[=:]\s*[\'\]?[\.\w]*[\'\]??另外,如果我想改变函数参数或其他一些奇怪的参数foo='bar'->foo='not_bara=1'或scale=size[0]/10->scale=size[0]/5,这在某种程度上可能吗?在实际使用过它之后,我似乎没有像我所想的那样真正理解regex和re.sub的用法。。如果我尝试使用它,我会在新脚本中获得大量的\x0/\x01字节。也许你可以完全实现你的答案?@AndersBB是的,类似的东西。或者,您可以将.*\n放在捕获名称的组后面,直到等号为止,用新的\u值参数中的任何内容替换该组后面的任何内容,直到行尾为止。如果新值是字符串形式,则它可以是任意值,因此它现在可以覆盖所有可能的情况,但要求赋值必须单独在一行上。如果我有时间和精力,今天晚些时候我将尝试调试一个正在运行的示例。如果你能提供所有可能被替换的参数形式,这会有所帮助。我编辑了我的原始帖子,将参数类型包含在main.py中。并非所有变量都应该更改,但最好能有一种方法来更改单行参数,例如浮点、字符串、列表、元组和表达式,例如256//n*alpha。优先顺序