如何在Python中通过字典重置值?
我有一个如何在Python中通过字典重置值?,python,yaml,pyyaml,Python,Yaml,Pyyaml,我有一个YAML文件无法提交到我的存储库,因为它包含密码和合理的信息。看起来是这样的: devops: branch: somebranch password: provider: digital_ocean: token: "" aws: bob: access_key_id: "XXX" secret_access_key: "XXX" jim
YAML
文件无法提交到我的存储库,因为它包含密码和合理的信息。看起来是这样的:
devops:
branch: somebranch
password:
provider:
digital_ocean:
token:
""
aws:
bob:
access_key_id:
"XXX"
secret_access_key:
"XXX"
jim:
access_key_id:
"XXX"
secret_access_key:
"XXX"
dev:
bob:
"secret"
jim:
"another secret"
app:
mom:
zookeeper:
"XXX"
admin:
"XXX"
import os
import yaml
with open(os.environ['DEVOPS_HOME'] + "/vagrant/server/settings.yml") as f:
settings = yaml.load(f)
for key in settings.keys():
settings[key]=0
如果我可以清除我文件中的所有密码,我将尝试在Python
中开发一个脚本。我可以将其提交到我的存储库中,在处理后应该是这样的:
devops:
branch: somebranch
password:
provider:
digital_ocean:
token:
""
aws:
bob:
access_key_id:
""
secret_access_key:
""
jim:
access_key_id:
""
secret_access_key:
""
dev:
bob:
""
jim:
""
app:
mom:
zookeeper:
""
admin:
""
我知道可以在字典中设置如下值:
devops:
branch: somebranch
password:
provider:
digital_ocean:
token:
""
aws:
bob:
access_key_id:
"XXX"
secret_access_key:
"XXX"
jim:
access_key_id:
"XXX"
secret_access_key:
"XXX"
dev:
bob:
"secret"
jim:
"another secret"
app:
mom:
zookeeper:
"XXX"
admin:
"XXX"
import os
import yaml
with open(os.environ['DEVOPS_HOME'] + "/vagrant/server/settings.yml") as f:
settings = yaml.load(f)
for key in settings.keys():
settings[key]=0
但是,这是我的输出:
{'password': 0, 'devops': 0}
有没有一种方法可以遍历我的字典并只为我的密码设置值?还是应该更改YAML文件的结构?您需要手动将密码部分中的每个字符串设置为空字符串。例如,如果您的字典如下所示:
{
'public_stuff': 'this should not be changed',
'password':
{
'category1':
{
'user': 'password'
},
'other_user': 'other_password',
},
}
可以在清除所有字符串值的函数中递归地执行此操作。如果涉及到字典值,它将对该值本身执行函数
def clear_password(content):
for key in content:
if isinstance(content[key], str):
content[key] = ""
elif isinstance(content[key], dict):
clear_password(content[key])
clear_password(settings["password"])
在Python 2中,
str
可能需要是basestring
或unicode
需要“擦除”值的键在命名上似乎没有规律性,但它们似乎有一个共同点,那就是它们都是键密码下的叶值。这使得递归成为一个选项,可以在不指定每个完整密钥路径的情况下将它们全部擦除
import sys
import ruamel.yaml
yaml_str = """\
nas:
devops:
branch: somebranch
password:
provider:
digital_ocean:
token:
""
aws:
bob:
access_key_id:
"XXX"
secret_access_key:
"XXX"
jim:
access_key_id:
"XXX"
secret_access_key:
"XXX"
dev:
bob:
"secret"
jim:
"another secret"
app:
mom:
zookeeper:
"XXX"
admin:
"XXX"
"""
def wipe_pass(data, key):
"""wipe the value if it is a string instance"""
if isinstance(data[key], type("")):
data[key] = ruamel.yaml.scalarstring.DoubleQuotedScalarString("")
return
if isinstance(data[key], dict):
for k in data[key]:
wipe_pass(data[key], k)
return
raise NotImplementedError # e.g. a YAML sequence
data = ruamel.yaml.round_trip_load(yaml_str, preserve_quotes=True)
wipe_pass(data, 'password')
ruamel.yaml.round_trip_dump(data, sys.stdout)
其中:
devops:
branch: somebranch
password:
provider:
digital_ocean:
token: ""
aws:
bob:
access_key_id: ""
secret_access_key: ""
jim:
access_key_id: ""
secret_access_key: ""
dev:
bob: ""
jim: ""
app:
mom:
zookeeper: ""
admin: ""
请注意,原始YAML的键值对格式不一致,其中值不是映射。这里的输出与原始的分支:somebranch
对一致
ruamel.yaml.scalarstring.DoubleQuotedScalarString(“”
是将“
作为输出所必需的。如果您只分配了”
,您将在YAML文件中获得空字符串的默认”
单引号
您可以尝试使用PyYAML执行上述操作,但您将丢失任何注释、不保证密钥顺序、丢失密码前面的空行:
以及可能更多的内容。这使得它在很大程度上无法用于往返数据(加载、修改、转储),而这些数据在提交之间必须有最小的更改
这是使用YAML 1.2解析器完成的,我是该解析器的作者。您可以只迭代密码部分的键吗?我正试图这样做@S.deMelo,但我不知道怎么做。我是Python新手。你能用一个例子告诉我怎么做吗?非常感谢@Anthon!我想你的意思是
wipe_pass
而不是clean_pass
函数中的wipe_pass
。@xZise是的,谢谢你指出。粘贴后,我重新命名了它,以确认我使用的评论术语。