Search code examples
pythonpropertiespython-multithreadingcallable-object

Python making the target of a Thread be a property setter


I have a class with:

  • A private instance attribute
  • Used property decorator to make a getter and a setter for the attribute

How can I make the setter be the target callable object of a threading.Thread?

The problem seems to be that the setter is not Callable. Is there a good workaround for this?


Sample Code

My current workaround is to make the setter without using the property decorator.

However, I would really like to not add a second setter. Is there a better way?

from threading import Thread


class SomeClass:
    def __init__(self):
        self._some_attr = 0

    @property
    def some_attr(self) -> int:
        return self._some_attr

    @some_attr.setter
    def some_attr(self, val: int):
        self._some_attr = val

    def set_some_attr(self, val: int):
        self._some_attr = val


some_class = SomeClass()

my_thread = Thread(target=SomeClass.set_some_attr, args=(some_class, 1))  # This works fine
my_thread.start()
my_thread.join()
print(some_class.some_attr)

my_thread2 = Thread(target=SomeClass.some_attr, args=  # How is this done?
my_thread2.start()
my_thread2.join()
print(some_class.some_attr)


Solution

  • SomeClass.some_attr returns a property object, which is indeed not callable. This property object has two attributes useful to you - the fget and fset attributes, which hold the getter and setter functions for that property. fget always points to a function, while fset might be None if no setter is defined.

    An example for using the setter in a separate thread:

    my_thread2 = Thread(target=SomeClass.some_attr.fset, args=(some_class, 1))
    my_thread2.start()
    my_thread2.join()
    print(some_class.some_attr)