Python превращение цели потока в средство задания свойств - PullRequest
0 голосов
/ 19 июня 2020

У меня есть класс с:

  • Атрибут частного экземпляра
  • Используется property декоратор для создания получателя и установщика для атрибута

Как я могу сделать сеттер целевым вызываемым объектом threading.Thread?

Проблема, похоже, в том, что сеттер не является вызываемым. Есть ли хороший обходной путь для этого?


Пример кода

Мой текущий обходной путь - сделать сеттер без использования декоратора property.

Однако мне бы очень хотелось не добавлять второй сеттер. Есть способ лучше?

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)

Ответы [ 2 ]

2 голосов
/ 23 июня 2020

kmaork ответ работает, но вы также можете просто использовать setattr:

thread = Thread(target=setattr, args=(obj, 'attrname', value))

Это позволяет не полагаться на какие-либо детали реализации того, как реализован атрибут. Вам не нужно делать сеттер целью; вам просто нужно, чтобы цель установила атрибут.

1 голос
/ 23 июня 2020

SomeClass.some_attr возвращает объект property, который действительно не вызывается. Этот объект свойства имеет два полезных для вас атрибута - атрибуты fget и fset, которые содержат функции получения и установки для этого свойства. fget всегда указывает на функцию, а fset может быть None, если сеттер не определен.

Пример использования сеттера в отдельном потоке:

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