Python 将属性设置为类';属性,其中后者是从类方法返回的

Python 将属性设置为类';属性,其中后者是从类方法返回的,python,Python,我有以下代码,它接受两个列表a和b,并返回一个Diff.Diff属性,这是一个包含三个dict()的列表。我希望能够使用属性的属性访问每个dict,如Diff.Diff.a、Diff.Diff.b等 现在,当我创建Diff类的新实例时,Diff.Diff是一个工作属性。然而,我得到的错误是 AttributeError:“list”对象没有属性“a” 在def\uuu init\uuu(…开始定义该子属性的行上 class Diff(object): def __init__(s

我有以下代码,它接受两个列表
a
b
,并返回一个
Diff.Diff
属性,这是一个包含三个
dict()
的列表。我希望能够使用属性的属性访问每个
dict
,如
Diff.Diff.a
Diff.Diff.b

现在,当我创建
Diff
类的新实例时,
Diff.Diff
是一个工作属性。然而,我得到的错误是

AttributeError:“list”对象没有属性“a”

def\uuu init\uuu(…
开始定义该子属性的行上

class Diff(object):   

    def __init__(self, a, b):
        self.a = dict(a)
        self.b = dict(b)

        Diff.diff = Diff.set_diff(self)
        Diff.diff.a = Diff.diff[0]
        Diff.diff.b = Diff.diff[1]
        Diff.diff.c = Diff.diff[2]

    def set_diff(self):
        # do something with self.a and self.b here
        return [{}, {}, {}] # returns a list with three items
我已经试着搜索这个问题,老实说,我不知道用什么搜索词…希望这不是一个重复的问题


编辑:

我的解决方案:

注意:我的代码使用
alpha
beta
gamaa
而不是
a
b
c

class DiffList(object):

    def __init__(self, a):
        assert isinstance(a, list) and len(a) == 3
        self.alpha = DiffListItem(a[0])
        self.beta = DiffListItem(a[1])
        self.gamma = DiffListItem(a[2])


class Diff(object):

    def __init__(self, a, b):
        assert isinstance(a, list) and isinstance(b, list)
        self.a = dict(a)
        self.b = dict(b)
        self.diff = DiffList(self.set_diff())

    def set_diff(self):
        # return the list with 3 dicts
        return a
现在,
Diff.Diff.alpha
等按预期返回列表中的dict。尽管此列表包装在一个
DiffListItem
对象中,该对象具有打印有序列表的函数

class DiffListItem(object):

    def __init__(self, a):
        assert isinstance(a, dict)        
        self.a = a

    def ordered_list(self):
        # Take a dict and sort by its value, returns a ordered list with entries
        # as lists as [key, value]
        keys = sorted(self.a, key=self.a.get, reverse=1)
        res = [[key, self.a[key]] for key in keys]    
        return res

希望这对其他人有帮助。我对编程相当陌生,还没有做太多OOP。Python为我介绍了它的功能。

Diff.Diff
是一个
列表,您不能通过属性访问它。相反,您可以用这些属性创建一个新对象。使用
Diff.Diff
(或更好的名称;它不是
列表
)定义为:

class DiffList(object):
    def __init__(self):
        self.a = {}
        self.b = {}
        self.c = {}
您可能应该将其用作实例,而不是类属性:

def __init__(self, a, b):
    self.a = dict(a)
    self.b = dict(b)
    self.diff = DiffList() # no need for a separate method
    self.diff.a # ...
然后您可以稍后访问它:

diff = Diff(a, b)
diff.diff.a # ...

我认为你想创造这样的东西:

class Diff(object):   
    a = None
    b = None
    c = None
    def __init__(self, a, b):
        self.a = dict(a)
        self.b = dict(b)

    #Do something here that modifies the diff.a, diff.b and diff.c 
    #attributes of the class like adding the dict to them

    def set_diff(self):
        # do something with self.a and self.b here
        return [{}, {}, {}] # returns a list with three items

通过键入Diff.Diff.a事件而不创建任何Diff类的对象,可以实现这种方式)您将拥有这些属性的属性。由
set_diff
返回的值是一个Python
list
对象。
list
对象是一种数据结构,它允许根据条目在数据结构中的位置按位置访问条目,非常类似于math类中的矩阵行(除了“条目”可以是任何类型的对象)

class Diff(object):   

    def __init__(self, a, b):
        self.a = dict(a)
        self.b = dict(b)

        Diff.diff = Diff.set_diff(self)
        Diff.diff.a = Diff.diff[0]
        Diff.diff.b = Diff.diff[1]
        Diff.diff.c = Diff.diff[2]

    def set_diff(self):
        # do something with self.a and self.b here
        return [{}, {}, {}] # returns a list with three items
您的代码要求名为
Diff.Diff
list
对象拥有一个属性
a
,该属性是对第0个条目的引用,依此类推。但这不是
list
类支持的数据访问类型

相反,您可以使用名为a
namedtuple
的特定数据类型,该数据类型具有命名属性
a
b
c
。在这种情况下,您的代码如下所示:

class Diff(object):   

    def __init__(self, a, b):
        self.a = dict(a)
        self.b = dict(b)
        self.diff = self.set_diff(self)

    def set_diff(self):
        # do something with self.a and self.b here
        from collections import namedtuple
        diff_tuple = namedtuple('diff_tuple', 'a b c')
        return diff_tuple({}, {}, {}) # returns a tuple with three named items

您不能在列表上设置任意属性;为什么您希望这样做?为什么您试图在
Diff
类对象上设置属性?您知道,每当创建
Diff
的对象时(因为您在
\uu init\uu
中对其进行修改),类上的值都将被覆盖,对吗?我没想到会这样做,只是尝试演示如何创建由同一类的元素共享的属性。但是为什么它会引发
NameError
(所以我学到了一点…:D)?因为名称
diff
不存在于类
diff
的范围内。如果希望它们是类属性,只需
a=None
就足够了,然后可以通过
diff.a
访问它们因为未定义
diff
。Python名称区分大小写。2)因为无法从类定义中访问类名(
diff.a=None
也不起作用)。但是,您可以在类定义中执行
a=None
。这将定义一个类变量,在实例化后可以通过
self
访问该类变量。@jonrsharpe噢,我总是忘记在Python中,thanks@JoelCornett最好通过
ClassName
访问类属性,否则它们会被i覆盖nstance属性。这与我想要的最接近。我认为此方法需要从
Diff
进行某种继承,因此
Diff.Diff
是它的子对象。但显然你不必这样做。我认为
Diff.Diff
一直是它自己类型的对象,而不是列表。现在一切都有意义了。谢谢!我是我接受了上面的答案,因为我认为
namedtuple
是我必须自己定义的东西。结果它是默认类型!谢谢你的帮助,我下次一定会尝试这种类型。