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

Python,意外行为:在对象实例中追加列表属性,python,Python,使用下面的代码,当我创建一个实例,然后将一个项附加到实例属性的列表中时,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

使用下面的代码,当我创建一个实例,然后将一个项附加到实例属性的列表中时,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

我被这弄糊涂了。将项目附加到实例属性列表的正确方法是什么?这就好像实例方法“看不到”列表中的所有项一样。

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

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

如果您确实希望
number\u of_stuff
属性动态反映
stuff
属性的长度,Python提供了一种使用
属性
装饰器的方法:

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

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

如果您确实希望
number\u of_stuff
属性动态反映
stuff
属性的长度,Python提供了一种使用
属性
装饰器执行此操作的方法:

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

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

您只是在第13行打印
一些内容。number\u of_stuff
时,该属性已初始化为
3
值(一些内容.number\u 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

您只是在打印第13行中的
部分内容。部分内容的编号
,当您打印(部分内容.部分内容的编号)时,该编号已初始化为
3
。要获取更新后的
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

您可以在
\uuuu init\uuuu
之外设置两个方法,一个用于
附加
self.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

您可以在
\uuuu init\uuuu
之外设置两个方法,一个用于
附加
self.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

如果您想创建一个具有可编辑属性的列表,那么应该创建一个继承内置
列表的类,而不是在类中创建一个列表

课堂材料(列表):
定义初始化(self,lst,other_stuff=None):
super().\uuuu init\uuuuu(lst)
self.other_stuff=另一个_stuff
然后,您会得到一个与列表行为完全相同的对象,但它也有一个
另一个\u stuff
属性:

>>l=Stuff(['a','b','c','d',另一个Stuff=42)
>>>l
['a','b','c','d']
>>>l.append('z')
>>>l
['a','b','c','d','z']
>>>莱恩(l)
5.
>>>l.另一件事
42

如果您想创建一个具有可编辑属性的列表,那么应该创建一个继承内置
列表的类,而不是在类中创建列表

课堂材料(列表):
定义初始化(self,lst,other_stuff=None):
super().\uuuu init\uuuuu(lst)
self.other_stuff=另一个_stuff
然后,您会得到一个与列表行为完全相同的对象,但它也有一个
另一个\u stuff
属性:

>>l=Stuff(['a','b','c','d',另一个Stuff=42)
>>>l
['a','b','c','d']
>>>l.append('z')
>>>l
['a','b','c','d','z']
>>>莱恩(l)
5.
>>>l.另一件事
42

您为什么希望这样做有效?您只在对象首次初始化时设置了
number\u of_stuff
属性,之后就再也不会更改它了。(此外,您还有一个可变的默认参数,它会导致其他问题,但不是这个特定问题的原因。)@RobinZigmond我知道哪里出了问题。我想要的是让属性填充方法调用的结果,这正是使用
@property
所能实现的。为什么您希望这样做?您只在对象首次初始化时设置了
number\u of_stuff
属性,之后就再也不会更改它了。(此外,您还有一个可变的默认参数,它会导致其他问题,但不是这个特定问题的原因。)@RobinZigmond我知道哪里出了问题。我想要的是让属性填充方法调用的结果,这正是使用
@property
实现的。谢谢,我意识到这可能与设置@property有关,但我现在真正理解了:DThank you,我意识到这可能与设置@property有关,但现在我真正理解了:D