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

时间:2017-04-07 23:28:52

标签: 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']

因此,对于每个“人”,我可以跟踪我可能有数据的多个事物,例如身高和体重。我称之为'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返回[10,20,30]

但是,如果需要,我还希望能够稍后附加到此列表,以便再次使用.add附加到现有列表。例如,mydict ['Person 10'] ['test scores']。add([1,2,3],'vals')应该允许我返回[10,20,30,1,2,3]来自mydict ['人10'] ['测试成绩']。vals。

我仍然非常习惯于面向对象的编程,类等。我对于实现我的目标可能存在的更好的策略非常开放,这只是一个嵌套的字典结构,我觉得它对于保存数据很方便。

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

谢谢!

2 个答案:

答案 0 :(得分:0)

根据我的理解,你想要一些可以方便地保存数据的东西。我实际上会构建一个类而不是嵌套字典,因为这样可以更简单地查看所有内容是如何一起工作的(这也有助于组织所有内容!)。

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类包含其实例的所有数据。如果要添加不同类型的数据,可以在 init ()函数中添加一个参数,如下所示:

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

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

如果这不是您想要的,或者您感到困惑,我愿意帮助您。

答案 1 :(得分:0)

我同意在这里使用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 []
    ...