Python,意外行为:在对象实例中附加列表属性

时间:2018-10-06 20:46:31

标签: python

使用以下代码,当我创建一个实例,然后将一个项目添加到instance属性的列表中时,instance方法不会注意到所添加的项目。

class Stuff:
    def __init__(self, stuff = []):
        self.stuff = stuff
        self.number_of_stuff = self.__len_stuff()

    def __len_stuff(self):
        return len(self.stuff)

# create an instance
some_stuff = Stuff(["notebook", "pencil", "eraser"])

# show stuff in instance
print(some_stuff.stuff)
# output: ['notebook', 'pencil', 'eraser']

# check how much stuff is in instance
print(some_stuff.number_of_stuff)
# output: 3

# add more stuff to instance
some_stuff.stuff.append("fidget spinner")
print(some_stuff.stuff)
# output: ['notebook', 'pencil', 'eraser', 'fidget spinner']

# check how much stuff is in instance again
print(some_stuff.number_of_stuff)
# output: 3

对此我感到很困惑。将项目追加到实例属性列表的正确方法是什么?好像实例方法以某种方式“看不到”列表中的所有项目。

5 个答案:

答案 0 :(得分:3)

如果您确实希望number_of_stuff属性能够动态反映stuff属性的长度,Python提供了一种使用property装饰器来做到这一点的方法:

@property
def number_of_stuff(self):
    return len(self.stuff)

这意味着您可以访问一个number_of_stuff属性,该属性会自动调用此方法并返回结果。

答案 1 :(得分:1)

您正在初始化构造函数中的self.number_of_stuff。当您追加到列表时,您会在列表中添加微调微调器,但不更新number_of_stuff变量。打印len(some_stuff.stuff)将按预期输出4。

答案 2 :(得分:0)

您只是在打印出some_stuff.number_of_stuff,当您在第13行执行3时,它已初始化为print(some_stuff.number_of_stuff)的值。要获取4的更新值,再次调用该函数以计算长度。这样的事情会起作用

class Stuff:
    def __init__(self, stuff = []):
        self.stuff = stuff
        self.number_of_stuff = self.len_stuff()

    def len_stuff(self):
        return len(self.stuff)

# create an instance
some_stuff = Stuff(["notebook", "pencil", "eraser"])

# show stuff in instance
print(some_stuff.stuff)
# output: ['notebook', 'pencil', 'eraser']

# check how much stuff is in instance
print(some_stuff.number_of_stuff)
# output: 3

# add more stuff to instance
some_stuff.stuff.append("fidget spinner")
print(some_stuff.stuff)
# output: ['notebook', 'pencil', 'eraser', 'fidget spinner']

# check how much stuff is in instance again
print(some_stuff.len_stuff()) #recalculating length
# output: 4

答案 3 :(得分:0)

您可以在__init__之外设置2种方法,一种从appendself.stuff,另一种用于收集项目数量。

class Stuff:
    def __init__(self, stuff = []):
        self.stuff = stuff

    def add_item(self, item):
        self.stuff.append(item)

    def no_items(self):
        return len(self.stuff)

some = Stuff(['notebook', 'pencil', 'eraser'])
print(some.stuff) # ['notebook', 'pencil', 'eraser']
print(some.no_items()) # 3

some.add_item('fidget spinner')
print(some.stuff) # ['notebook', 'pencil', 'eraser', 'fidget spinner']
print(some.no_items()) # 4

答案 4 :(得分:0)

如果要创建具有可编辑属性的列表,则应创建一个继承自内置list的类,而不是在类中具有列表。

class Stuff(list):
    def __init__(self, lst, another_stuff=None):
        super().__init__(lst)
        self.another_stuff = another_stuff

然后您将获得一个对象,该对象的行为完全类似于列表,但也具有another_stuff属性:

>>> l = Stuff(['a', 'b', 'c', 'd'], another_stuff=42)
>>> l
['a', 'b', 'c', 'd']
>>> l.append('z')
>>> l
['a', 'b', 'c', 'd', 'z']
>>> len(l)
5
>>> l.another_stuff
42