【问题标题】:Adding a descriptor to a Python subclass将描述符添加到 Python 子类
【发布时间】:2015-08-06 16:34:38
【问题描述】:

我有一个继承优先级队列的 python 类,我还使用描述符向该类添加属性,如下所示:

from Queue import PriorityQueue
class My_Class(PriorityQueue):
    my_attr = NonNegativeInt(0)

    def __init__(self):
        PriorityQueue.__init__(self)

描述符是这样实现的:

class NonNegativeInt(object):
  def __init__(self, default):
      self.default = default
      self.data = WeakKeyDictionary()

  def __get__(self, instance, owner):
      return self.data.get(instance, self.default)

  def __set__(self, instance, value):

      if type(value) is not int:
          raise TypeError('Value must be an int')

      if value < 0:
          raise ValueError("Value must be above 0")

       self.data[instance] = value

当我致电My_Class.my_attr = -1 时,我没有收到任何异常。但是,如果我将 My_Class 更改为此,我会得到异常:

class My_Class(object):
    my_attr = NonNegativeInt(0)

    def __init__(self):
        pass

有趣的是,My_Class 的第一个实现以my_attr 属性开头,它只是不执行NonNegativeInt 中的__set__ 函数。

为什么改变超类会改变我的描述符的工作方式?是否与这条线有关:PriorityQueue.__init__(self)?我怎样才能给子类我想要的行为?

【问题讨论】:

  • 你的意思是你继承自object(小写),并且你在My_Class的instance上设置属性,对吧?
  • 那么PriorityQueue从何而来?
  • 是的,我继承自 object,这只是一个错字。
  • PriorityQueue来自Queue,又一个错字

标签: python inheritance subclass descriptor python-descriptors


【解决方案1】:

描述符仅适用于新型类(直接或间接继承自object 的类)。对旧式类上的描述符 __get__ 方法有一些支持,但这种支持是有限的。

您使用的PriorityQueue 类可能不是从object 继承的。如果这是Queue.PriorityQueue class,那肯定是这样,该模块中的类都是老式的。

您拨打PriorityQueue.__init__的事实与此无关。

【讨论】:

  • 如果我将My_Class 更改为此,它似乎工作:class My_Class(PriorityQueue, object):。有什么理由我应该避免这种情况吗?
  • @devin: 如果你要使用super() 来访问被覆盖的方法,或者使用多重继承(过去在object 中混合)可能会有问题,但是对于你的用例我 认为应该没问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-15
  • 1970-01-01
  • 2012-02-24
  • 1970-01-01
  • 2021-04-13
  • 2013-09-04
  • 1970-01-01
相关资源
最近更新 更多