自动将值附加到现有属性或创建并填充新属性的Python类

自动将值附加到现有属性或创建并填充新属性的Python类,python,class,dictionary,spyder,attr,Python,Class,Dictionary,Spyder,Attr,我在这里的目标是能够创建嵌套字典,这些字典具有保存值列表的属性。例如,我希望能够做到以下几点: mydict['Person 1']['height'].vals = [23, 25, 32] mydict['Person 2']['weight'].vals = [100, 105, 110] mydict['Person 2']['weight'].excel_locs ['A1', 'A2', 'A3'] def __init__(self, name=None, testScores=

我在这里的目标是能够创建嵌套字典,这些字典具有保存值列表的属性。例如,我希望能够做到以下几点:

mydict['Person 1']['height'].vals = [23, 25, 32]
mydict['Person 2']['weight'].vals = [100, 105, 110]
mydict['Person 2']['weight'].excel_locs ['A1', 'A2', 'A3']
def __init__(self, name=None, testScores=None, weight = None):
    self.name = name
    self.testScores = testScores
    self.weight = weight
因此,对于每个“人”,我可以跟踪我可能有数据的多个方面,比如身高和体重。我称之为“VAL”的属性只是高度或权重值的列表。重要的是,我希望能够跟踪原始数据的来源,例如它在Excel电子表格中的位置

以下是我目前的工作内容:

import collections
class Vals:
    def add(self, list_of_vals=[], attr_name=[]):
        setattr(self, attr_name, val)

    def __str__(self):
        return str(self.__dict__)
mydict = collections.defaultdict(Vals)
因此,我希望能够根据需要添加新的键,如mydict['Person 10']['test scores'],然后创建一个新属性,如“vals”,如果它不存在,还可以在其中添加新值

我想要实现的示例:

mydict['Person 10']['test scores'].add([10, 20, 30], 'vals')
这将允许mydictmydict['Person 10']['test scores'].vals返回[10,20,30]

但是,如果需要的话,我还希望以后能够附加到此列表,例如使用.add再次附加到现有列表。例如,mydict['Person 10']['test scores'].add([1,2,3],'VAL')应该允许我从mydict['Person 10']['test scores']返回[10,20,30,1,2,3]

我仍然非常习惯于面向对象编程、类等。我非常愿意采用更好的策略来实现我的目标,这只是一个嵌套的字典结构,我发现它便于保存数据

如果我们只是修改上面的VAL类,它需要一种确定属性是否存在的方法。如果是,请创建并用列表\ VAL填充它,否则将附加到现有列表


谢谢

据我所知,您需要一种可以方便地保存数据的东西。实际上,我会构建一个类而不是一个嵌套的字典,因为这样可以更容易地查看所有内容是如何协同工作的(同时也有助于组织所有内容!)

基本上,Person类保存它的一个实例的所有数据。如果要添加不同类型的数据,可以向init()函数添加如下参数:

mydict['Person 1']['height'].vals = [23, 25, 32]
mydict['Person 2']['weight'].vals = [100, 105, 110]
mydict['Person 2']['weight'].excel_locs ['A1', 'A2', 'A3']
def __init__(self, name=None, testScores=None, weight = None):
    self.name = name
    self.testScores = testScores
    self.weight = weight
您可以像编辑变量一样编辑这些值


如果这不是您想要的,或者您感到困惑,我愿意尝试为您提供更多帮助。

据我所知,您需要可以方便地保存数据的东西。实际上,我会构建一个类而不是一个嵌套的字典,因为这样可以更容易地查看所有内容是如何协同工作的(同时也有助于组织所有内容!)

基本上,Person类保存它的一个实例的所有数据。如果要添加不同类型的数据,可以向init()函数添加如下参数:

mydict['Person 1']['height'].vals = [23, 25, 32]
mydict['Person 2']['weight'].vals = [100, 105, 110]
mydict['Person 2']['weight'].excel_locs ['A1', 'A2', 'A3']
def __init__(self, name=None, testScores=None, weight = None):
    self.name = name
    self.testScores = testScores
    self.weight = weight
您可以像编辑变量一样编辑这些值


如果这不是您想要的,或者您感到困惑,我愿意尝试为您提供更多帮助。

我同意在这里使用
人员
类是更好的解决方案。这是一种更抽象、更直观的表示概念的方法,它将使您的代码更易于使用

看看这个:

class Person():

    # Define a custom method for retrieving attributes
    def __getattr__(self, attr_name):
        # If the attribute exists, setdefault will return it.
        # If it doesn't yet exist, it will set it to an empty
        # dictionary, and then return it.
        return self.__dict__.setdefault(attr_name, {})

carolyn = Person()
carolyn.name["value"] = "Carolyn" 
carolyn.name["excel_loc"] = "A1"

print(carolyn.name)
# {"value": "Carolyn", "excel_loc": "A1"}

maria = Person()
print(maria.name)
# {}
然后,将人们收集到字典中是很容易的:

people = {
    "carolyn": carolyn,
    "maria": maria
}
people["Ralph"] = Person()
people["Ralph"].name["value"] = "Ralph"
在定义
add
方法时,您还犯了一个棘手的错误:

def add(self, list_of_vals=[], attr_name=[]):
    ...
在Python中,您永远不希望将空列表设置为默认变量。由于它们存储在引擎盖下的方式,您的默认变量每次都会引用相同的列表,而不是每次都创建一个新的空列表。 以下是一个常见的解决方法:

def add(self, list_of_vals=None, attr_name=None):
    list_of_vals = list_of_vals or []
    attr_name = attr_name or []
    ...

我同意在这里使用
Person
类是更好的解决方案。这是一种更抽象、更直观的表示概念的方法,它将使您的代码更易于使用

看看这个:

class Person():

    # Define a custom method for retrieving attributes
    def __getattr__(self, attr_name):
        # If the attribute exists, setdefault will return it.
        # If it doesn't yet exist, it will set it to an empty
        # dictionary, and then return it.
        return self.__dict__.setdefault(attr_name, {})

carolyn = Person()
carolyn.name["value"] = "Carolyn" 
carolyn.name["excel_loc"] = "A1"

print(carolyn.name)
# {"value": "Carolyn", "excel_loc": "A1"}

maria = Person()
print(maria.name)
# {}
然后,将人们收集到字典中是很容易的:

people = {
    "carolyn": carolyn,
    "maria": maria
}
people["Ralph"] = Person()
people["Ralph"].name["value"] = "Ralph"
在定义
add
方法时,您还犯了一个棘手的错误:

def add(self, list_of_vals=[], attr_name=[]):
    ...
在Python中,您永远不希望将空列表设置为默认变量。由于它们存储在引擎盖下的方式,您的默认变量每次都会引用相同的列表,而不是每次都创建一个新的空列表。 以下是一个常见的解决方法:

def add(self, list_of_vals=None, attr_name=None):
    list_of_vals = list_of_vals or []
    attr_name = attr_name or []
    ...