0

我有一堂课:

  • 私有实例属性
  • 使用property装饰器为属性创建 getter 和 setter

如何使 setter 成为 a 的目标可调用对象threading.Thread

问题似乎是 setter 不可调用。有没有好的解决方法?


示例代码

我目前的解决方法是在不使用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)

4

2 回答 2

2

kmaork 的答案有效,但您也可以使用setattr

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

这避免了依赖于如何实现属性的任何实现细节。您无需将 setter 设为目标;你只需要让目标设置属性。

于 2020-06-23T10:20:58.377 回答
1

SomeClass.some_attr返回一个property对象,该对象确实不可调用。此属性对象有两个对您有用的属性 -fgetfset属性,它们包含该属性的 getter 和 setter 函数。fget总是指向一个函数,而如果没有定义 setter 则fset可能是。None

在单独的线程中使用 setter 的示例:

my_thread2 = Thread(target=SomeClass.some_attr.fset, args=(some_class, 1))
my_thread2.start()
my_thread2.join()
print(some_class.some_attr)
于 2020-06-23T10:13:03.163 回答