python - 子类化属性在 __init__ 上引发 TypeError

标签 python concurrency properties

我对属性进行了子类化,尝试为其添加锁,以便对它的访问是原子的(一次只有一个线程可以读取和写入它)。但我在初始化程序时遇到了错误,并且无法找出原因。

需要明确的是:我不想创建描述符,我希望能够使用@atomic_property装饰器而不是@property

class atomic_property(property):

    def __init__(self, func, name=None, doc=None):
        self.__name__ = name or func.__name__
        self.__module__ = func.__module__
        self.__doc__ = doc or func.__doc__
        self.func = func
        self.lock = threading.Lock()

    def __get__(self, obj, objtype=None):
        with self.lock:
            return self.func(obj)

    def __set__(self, obj, value):
        with self.lock:
            return self.func(obj, value)

这是来自 ipython 的回溯。

    In [12]: class a(object):
    def __init__(self):
        self._b = 1
    @utils.atomic_property
    def b(self):
        return self._b
    @b.setter
    def b(self, val):
        self._b = val
   ....:         
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-12-daec89385bc3> in <module>()
----> 1 class a(object):
      2     def __init__(self):
      3         self._b = 1
      4     @utils.atomic_property
      5     def b(self):

<ipython-input-12-daec89385bc3> in a()
      5     def b(self):
      6         return self._b
----> 7     @b.setter
      8     def b(self, val):
      9         self._b = val

TypeError: __init__() takes from 2 to 4 positional arguments but 5 were given

最佳答案

您距离使用代码正确子类化 property 还很远:这一次 您重写了一些方法,但从不关心调用上游方法,以便它可以完成其业务。

并不是说不能以这种方式完成,如果您实际上在子类中重现了父类(super class)上的方法将执行的所有行为 - 但即使不查看父类(super class)的代码(在 cPython 的情况下是 native 代码) ) - 我们可以看到 self.func 要么是 getter 函数,要么是 setter 函数 - 不能两者兼而有之。

如果您只关心注释您将使用的属性并执行您想要的操作,并将其余部分委托(delegate)给原始代码,那么它将非常有用 可能只是工作:

class atomic_property(property):

    def __init__(self,*args, **kw):
        super(atomic_property, self).__init__(*args, **kw)
        self.lock = threading.Lock()

    def __get__(self, obj, obj_type):
        with self.lock:
            return super(atomic_property, self).__get__(obj, objtype)

    def __set__(self, obj, value):
        with self.lock:
            return super(atomic_property, self).__set__(obj, value)

关于python - 子类化属性在 __init__ 上引发 TypeError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37927612/

相关文章:

python - 为 Django 管理员扩展 base_site.html

python - 将列表中的每个数据帧保存到单独的 csv 文件

python - raw_input 不在 readline 中留下历史记录

C#多线程并发算法

动态添加属性和 setter 的 Pythonic 方式

html - CSS 中的属性值区分大小写吗?

javascript - 元素属性与其对应属性之间关系背后的设计原因

python - 为什么 pytesseract 抛出 WinError 6?

java - 在 JFrame Java 中闪烁

swift - Swift 中没有信号量的并发