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

Python class that automatically appends values to existing attribute OR creates and fills new attribute

我的目标是能够创建具有保存值列表的属性的嵌套字典。例如,我希望能够做这样的事情:

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']

因此,对于每个 "person",我都可以跟踪我可能拥有数据的多项内容,例如身高和体重。我调用的属性 'vals' 只是身高或体重值的列表。重要的是,我希望能够跟踪原始数据的来源,例如它在 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 到 return [10, 20, 30]

但是我也希望能够在以后需要时追加到此列表,以便再次使用 .add 追加到现有列表。例如,mydict['Person 10']['test scores'].add([1, 2, 3], 'vals') 应该允许我 return [10, 20, 30, 1, 2, 3] 来自 mydict['Person 10']['test scores'].vals.

我仍然非常习惯面向对象的编程,classes 等。我非常愿意接受可能存在的更好的策略来实现我的目标,这只是一个嵌套的字典结构我发现保存数据很方便。

如果我们只是修改上面的Vals class,它需要一种方法来判断一个属性是否存在。如果是这样,创建并用 list_of_vals 填充它,否则附加到现有列表

谢谢!

据我了解,您想要可以方便地保存数据的东西。我实际上会构建一个 class 而不是嵌套字典,因为这样可以更轻松地查看所有内容如何协同工作(并且它还有助于组织所有内容!)。

class Person(object):
    """__init__() functions as the class constructor"""
    def __init__(self, name=None, testScores=None):
        self.name = name
        self.testScores = testScores


# make a list of class Person(s)
personList = []
personList.append(Person("Person 1",[10,25,32]))
personList.append(Person("Person 2",[22,37,45]))

print("Show one particular item:")
print(personList[0].testScores)
personList[0].testScores.append(50)
print(personList[0].testScores)

print(personList[1].name)

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

def __init__(self, name=None, testScores=None, weight = None):
    self.name = name
    self.testScores = testScores
    self.weight = weight

您可以像编辑变量一样编辑这些值。

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

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

看看这个:

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 []
    ...