0

Say I have a class:

class Foo(object):
    def __init__(self):
        self.some_attr = ''
        self.a_list = []
        self.empty_check = bool(self.a_list)
myFoo = Foo()
myFoo.a_list.append(1)

Much like this user, I want empty_check to change to True all by itself, without me having to do anything else, as soon as something is appended to the list. As it is above, myFoo.empty_check is still False. However, I want mine to go "one way". That is, I don't want myFoo.empty_check = True to change myFoo.a_list into []. (So technically not a duplicate, right?)

How can I accomplish this?

It seems I should be using property setters, but despite googling around for a few hours, including reading up on the linked question, I still don't understand how to do this.

NightShadeQueen
  • 3,284
  • 3
  • 24
  • 37
michen00
  • 764
  • 1
  • 8
  • 32

2 Answers2

1

You should use a property , the property would be evaluated everytime you try to access it, so you would end up checking the latest self.a_list . Also, if you only specify the getter for the property, without setter, you would not be able to do - myFoo.empty_check = True , etc. Example -

class Foo(object):
    def __init__(self):
        self.some_attr = ''
        self.a_list = []
    @property
    def empty_check(self):
        return bool(self.a_list)
myFoo = Foo()
print(myFoo.empty_check)
myFoo.a_list.append(1)
print(myFoo.empty_check)

Example/Demo -

>>> class Foo(object):
...     def __init__(self):
...         self.some_attr = ''
...         self.a_list = []
...     @property
...     def empty_check(self):
...         return bool(self.a_list)
...
>>> myFoo = Foo()
>>> print(myFoo.empty_check)
False
>>> myFoo.a_list.append(1)
>>> print(myFoo.empty_check)
True
>>> myFoo.empty_check = True
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
Anand S Kumar
  • 88,551
  • 18
  • 188
  • 176
1

This should do it (I changed some things to follow better practices):

class Foo(object):
    def __init__(self):
        self.some_attr = ''
        self.a_list = []

    @property
    def is_empty(self):
        return not self.a_list

Demonstration:

>>> my_foo = Foo()
>>> print(my_foo.is_empty)
True
>>> my_foo.a_list.append(1)
>>> print(my_foo.is_empty)
False
>>> my_foo.is_empty = True
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
>>> 

A property essentially gives you the syntax of accessing an attribute's value, while behind the scenes it's calling a method. Properties aren't just for getting a value; you can also use them for setting and deleting. For more information, see the property documentation.

Cyphase
  • 11,502
  • 2
  • 31
  • 32