【问题标题】:trying to return a dict, get none instead试图返回一个字典,而不是得到一个
【发布时间】:2020-03-15 01:41:07
【问题描述】:

我正在尝试创建一个 python 程序,它可以自动生成类文件,给定特定格式的输入。为了简化数据的存储和解析,我定义了一个名为 Class_Dict 的类,其中包含单个类的规范。输入时,数据如下:

class name : attr1, attr2, attr3 : method1, method 2

机器将其理解为:

{"class_name" : ['attr1,attr2,attr3', 'method1,method2']}

注意:我称对象为“Class_Dict”,但称其为键值对更公平。我想强调一下——类 dict 对象应该与容器(也是一个字典)区分开来,容器可以保存许多键值对,每个键值对指定一个要生成的新类。

所以,为了处理继承,我定义了一个表示它的语法,以及一个解析输入格式并创建 class_dict 对象的函数。基本上,它遍历 class_container 字典中的每个键值对,如果其中有一个“>”(指定父子关系),那么它会调用该条目的继承函数。继承函数接受一个详细说明继承层次结构并构建适当类的条目。例如,如果我们有:

classA, classB > classC : A1, A2 / B1, B2 > C1, C2, C3 : Amethod1 / Bmethod1 > Cmethod2

那么classA和classB是classC的父母,所以在机器里:

{"classA, classB > classC" : "A1, A2 / B1, B2 > C1, C2, C3","Amethod / Bmethod > Cmethod"}

变成:

{ClassA : [A1, A2],[Amethod], ClassB : [B1, B2],[Bmethod], ClassC(ClassA, ClassB) : [C1, C2, C3], [Cmethod]}

至少,这就是我想要完成的。我有一些设计问题阻止我以直接的方式实现它。也就是说,Class_Dict(封装一个类的规范的对象)是不可迭代的,所以一旦我做了应用继承规则的转换,我就不能简单地做

#psuedocode
del class_container[old entry]
class_container.update(new_entry) #because new_entry is a type Class_Dict, not an iterable

我找不到使 Class_Dict Iterable 的方法,因为它是一个单一的东西。我想我可以通过给它 iternext 方法将它硬塞进一个可迭代对象中,而无需为它们实现有意义的功能。

还有第二个问题,即您不能在循环遍历字典时调整其大小(必须循环以确定要在哪些条目上运行继承函数)。这对实现意味着我必须在继承函数内部有一个单独的字典,其中包含新生成的 class_dicts,然后返回它并使用返回值更新 class_container。我遇到的问题是我的代码在继承函数中产生了有效的结果(使用类型 dict),然后我返回这些结果并获得 None/Nonetype。我的猜测是因为我用 Class_Dict(a,b,c).repr() 更新了“new”(本地字典),而这实际上并没有在内存中构造它所必需的对象存储在一个运行时数据结构中(我对python的实现了解不多,只是随便看看)

代码:

class_container = {}

def from_file(f):
    """
builds a container out of text file
containing class dict specifications.
    """    
    #need to account for lack of .txt in POSIX systems
    with open("{}.txt".format(f), "r") as file:
        for lines in file:
            #if line format OK:
            class_container.update(Class_Dict.to_dict(lines.strip("\n")))
            #else:
            ###throw an error cuz no bueno


def inheritance(name, attr, methods, new = {}):
    family, family_attr, family_methods = name.split(">"), attr.split(">"), methods.split(">")
    #error checking: does the numbers of ops match up. can not proceed if no.
    parents, parent_attr, parent_methods = family[0].split(","), family_attr[0].split("/"), family_methods[0].split("/")
    for a, b, c in zip(parents, parent_attr, parent_methods):
        new.update(Class_Dict(a,b,c).__repr__())
    del family[0], family_attr[0], family_methods[0]
    name, attr, methods = ">".join(family), ">".join(family_attr), ">".join(family_methods)
    if len(family) > 0:
        inheritance(name, attr, methods)
    else:
        return(new)


from_file("classes")
for entries in class_container:
    if entries.count(">") > 0:
        class_container.update(inheritance(entries, class_container[entries][0], class_container[entries][1]))
        #del class_container[entries]
        #class_container.extend(new)

【问题讨论】:

  • 嗨,breadman0,欢迎来到 StackOverflow。为了让我们更好地理解你的问题,你能给我们你想出的Class_Dict的代码吗?您能否提供classes.txt 文件的示例?如果你有一个文本输出,它会是什么样子?
  • EvensF- 我能做到。但是,我解决了这个问题 - 删除这篇文章或根据我的进度更新它会更好吗?
  • 好吧,也许写下你自己的答案,这样如果其他人有同样的问题,可以帮助他们。

标签: python function dictionary oop local-variables


【解决方案1】:

所以我的问题是我的基本案例的主体:

if len(family) > 0:
   inheritance(name, attr, methods)

没有返回值。只需将其修改为此即可解决问题。

if len(family) > 0:it 
   return inheritance(name, attr, methods)

我对这解决问题的原因很感兴趣。这似乎很自相矛盾 - 较早返回 None 的事实意味着 else 情况永远不会被触发,但它必须为了让函数返回所需的值。让基本情况返回递归调用有何不同?

【讨论】:

    猜你喜欢
    • 2014-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多