Python: 动态存储字典访问权限

2 投票
1 回答
764 浏览
提问于 2025-04-18 15:52

我试着找出怎么做这个(谷歌、StackOverflow等),但我可能用错了关键词...

基本上,我是逐行读取一个文件,如果遇到一个关键词,我想把它作为字典的键添加进去。不过,我想把它的值作为这个字典的一个子字典,然后后面再遇到的关键词都作为这个子字典的子项(以此类推),除非我遇到一个结束符号,这样就可以回到上一级字典。

示例文件:

def myitem {
    def aSubItem {
        abc
    }
    def anotherSubItem {
        hi!
        hows you?
    }
}

所以我想得到一个这样的字典:

mydict = {
    "myitem" : {
        "aSubItem" : { "abc" },
        "anotherSubItem" : { "hi!", "hows you?" }
    }
}

基本上,我在寻找一种方法来存储当前的深度(或者字典的访问层级),比如,你可以通过 mydict['myitem']['aSubItem'] 来访问 'abc',但我想能够存储我当前的深度,以防有人在这个块里添加东西... 所以类似于:

curLevel = ['myitem']['aSubItem']

然后我可以告诉 mydict 访问 curLevel,当这个块结束(遇到 })时,我可以告诉它上升“一级”到

curLevel = ['myitem']

===================

我知道我可以使用

curLevel = mydict

这样我就可以通过 curLevel 来访问 myDic... 这在向下进入字典层级时很好用...

但是,我该怎么上升一级呢?也就是说,如果我有:

curLevel = mydict['myitem']['aSubItem']

我该怎么去到

curLevel = mydict['myitem']

====================

这里有一些示例代码,因为大家都喜欢示例代码 :P

这段代码在向下进入字典时是有效的,我只是还不确定怎么让它回到上面去

import os
import re

# file location
fle = "myfilelocation"
# read file contents
fh = open(fle, 'r')
content = fh.readlines()

# The dictionary to hold the structure
structure = {}
# reference to structure that we will use in the loop
cur = structure

# loop through file lines
for line in content:

    # Match our starting def line ( def ___ { )
    st = re.match(r'\s*Def\s([^{\s]+)', line, re.IGNORECASE)
    if st:
        cur[st.group(1)] = {}
        cur = cur[st.group(1)]

    # Match the close of a block ( } )
    ed = re.match(r'\s*}\s*', line)
    if ed:
        # ??? How do I tell it to go up one dict level??
        None

    # If its neither, add to current level of array
    # Don't mind the inefficiency here, I'll be improving it later
    if not st and not ed and not re.match(r'\s*{\s*$', line) and not re.match(r'\s*$', line):
        # Not implemented yet
        None

print(structure)

目前上面示例代码的输出结果是这样的

mydict = {
    "myitem" : {
        "aSubItem" : {
            "anotherSubItem" : {}
            }
        }
    }
}

如果需要更多信息,我很乐意提供 :)

(是的,我知道我可能可以使用解析器... 但我真的没有找到任何一个能用的... 而且,从头开始写东西是个很好的练习 xD)

1 个回答

1

正如你所注意到的,子节点并不会自动知道它们的父节点,所以你不能简单地“回去”。

你需要明确地给它们提供这些父节点的引用,可以用一个特殊的键,比如 __parent,或者用一个不会和实际键重复的东西,或者你可以保持一个单独的列表,这个列表就像一个“栈”,用来记录你在树中的当前路径,随着你向下走添加新的层级,想要回到父节点时就把它们弹出。

curLevel = ['myitem']['aSubItem'] 这个写法差不多,但不太好用,直接用一个列表 curLevel = ['myitem', 'aSubItem'],然后在需要的时候用 append 添加和用 pop 弹出就可以了。

根据你的需求,你可以选择在列表中保存字典的引用,或者只保存键,然后通过这些键从基础对象向上查找。

撰写回答