Я оставляю свое исходное решение для потомков:
CONTEXT = {
"database": {
"port": 9990,
"users": ["number2", "dr_evil"]},
"admins": ["number2@virtucon.com", "dr_evil@virtucon.com"],
"domain": {"name": "virtucon.com"}}
def getitem(context, *keys):
node = context
for key in keys:
node = node[key]
return node
if __name__ == "__main__":
print getitem(CONTEXT, "database")
print getitem(CONTEXT, "database", "port")
print getitem(CONTEXT, "database", "users", 0)
print getitem(CONTEXT, "admins")
print getitem(CONTEXT, "domain", "name")
try:
getitem(CONTEXT, "database", "nosuchkey")
except KeyError, e:
print "Error:", e
Но вот версия, которая реализует подход, аналогичный интерфейсу getitem, предложенному doublep. Я специально не работаю с пунктирными ключами, а скорее делаю ключи в отдельных вложенных структурах, потому что это кажется мне чище:
CONTEXT = {
"database": {
"port": 9990,
"users": ["number2", "dr_evil"]},
"admins": ["number2@virtucon.com", "dr_evil@virtucon.com"],
"domain": {"name": "virtucon.com"}}
if __name__ == "__main__":
print CONTEXT["database"]
print CONTEXT["database"]["port"]
print CONTEXT["database"]["users"][0]
print CONTEXT["admins"]
print CONTEXT["domain"]["name"]
try:
CONTEXT["database"]["nosuchkey"]
except KeyError, e:
print "Error:", e
Вы можете заметить, что я действительно здесь сделал, исключил всякую церемонию доступа к структуре данных. Вывод этого скрипта такой же, как и оригинал, за исключением того, что он не содержит точечный ключ. Мне кажется, это более естественный подход, но если вы действительно хотите иметь возможность работать с точечными ключами, вы можете сделать что-то вроде этого:
CONTEXT = {
"database": {
"port": 9990,
"users": ["number2", "dr_evil"]},
"admins": ["number2@virtucon.com", "dr_evil@virtucon.com"],
"domain": {"name": "virtucon.com"}}
def getitem(context, dotted_key):
keys = dotted_key.split(".")
value = context
for key in keys:
try:
value = value[key]
except TypeError:
value = value[int(key)]
return value
if __name__ == "__main__":
print getitem(CONTEXT, "database")
print getitem(CONTEXT, "database.port")
print getitem(CONTEXT, "database.users.0")
print getitem(CONTEXT, "admins")
print getitem(CONTEXT, "domain.name")
try:
CONTEXT["database.nosuchkey"]
except KeyError, e:
print "Error:", e
Я не уверен, каким было бы преимущество такого подхода.