我能够迭代YAML配置文件并执行每个部分所需的所有操作。除了嵌套的for循环之外,有什么方法可以使用更加pythonic代码实现相同的结果吗?
import yaml
with open('/tmp/cfg_demo.yaml') as yfile:
cfg = yaml.safe_load(yfile)
for header, subsections in cfg.iteritems():
for section, key in subsections.iteritems():
for values in key:
for field, value in values.iteritems():
if section == 'permission_assign':
# execute service to handle permissions
print section, field, value
elif section == 'group_assign':
# execute service to handle group permissions
print section, field, value
elif section == 'group_users_assign':
# execute service to handle user permissions
print section, field, value
elif section == 'new_users':
# Execute service to handle user creation
print section, field, value
cfg_demo.yaml内容:
access_management:
permission_assign:
- sample_1: service:1
- sample_2: service:2
group_assign:
- sample_1: Group_1
- sample_2: Group_2
group_users_assign:
- Group_1: User_a User_b
new_users:
- User_a: user_pwd
- User_b: user_pwd
输出:
permission_assign sample_1 service:1
permission_assign sample_2 service:2
group_assign sample_1 Group_1
group_assign sample_2 Group_2
group_users_assign Group_1 User_a User_b
new_users User_a user_pwd
new_users User_b user_pwd
答案 0 :(得分:0)
由于键permission_assign
,group_assign
等必然会比使用有序键值对信息打印更有用,我会根据这些信息创建不同类的对象。
from __future__ import print_function
from ruamel import yaml
from collections import OrderedDict
with open('cfg_demo.yml') as fp:
cfg = yaml.safe_load(fp)
class SectionMap(dict):
def add(self, cls):
name = ''.join([n if n.islower() else '_' + n.lower() for n in cls.__name__])
if name[0] == '_':
name = name[1:]
cls.name = name
self[name] = cls
section_map = SectionMap()
class AssignedFieldValue:
def __init__(self, args):
self.values = OrderedDict()
for x in args:
for k in x:
self.values[k] = x[k]
def dump(self):
for k in self.values:
v = self.values[k]
print(self.name, k, v)
class PermissionAssign(AssignedFieldValue):
pass
section_map.add(PermissionAssign)
class GroupAssign(AssignedFieldValue):
pass
section_map.add(GroupAssign)
class GroupUsersAssign(AssignedFieldValue):
pass
section_map.add(GroupUsersAssign)
class NewUsers(AssignedFieldValue):
pass
section_map.add(NewUsers)
for header in cfg:
subsections = cfg[header]
for section_name in subsections:
section = section_map[section_name](subsections[section_name])
section.dump()
这与您提供的输出打印相同,但循环更简单。
这样你就可以摆脱通过扩展类,然后添加特定的,真实的功能。只需将section.dump()
替换为section.do()
,并为每个do()
子类实施方法AssignedFieldValue
。
如果您可以更改YAML,那么我会将其更改为包含标签:
access_management:
- !permission_assign
sample_1: service:1
sample_2: service:2
- !group_assign
sample_1: Group_1
sample_2: Group_2
- !group_users_assign
Group_1: User_a User_b
- !new_users
User_a: user_pwd
User_b: user_pwd
基于适当的构造函数并使用round_trip_load()
(保留键值对的顺序),您可以加载此YAML并直接生成节,而无需SectionMap()
个东西。这更像是Pythonic,更好地利用了YAML功能。
请注意{3}在Python3中消失了,因此iteritems()
作为声明。上面的代码将在Python 2和3中运行