向 Python 子类添加描述符
Adding a descriptor to a Python subclass
我有一个 python class 继承了优先级队列,我还使用描述符向 class 添加了一个属性,如下所示:
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__
函数。
为什么更改 superclass 会改变我的描述符的工作方式?是否与这一行有关:PriorityQueue.__init__(self)
?我怎样才能给 subclass 我想要的行为?
描述符仅适用于 新式 classes(直接或间接继承自 object
的那些)。在旧式 classes 上对描述符 __get__
方法有一些支持,但这种支持是有限的。
您正在使用的 PriorityQueue
class 可能不是从 object
继承的。如果是Queue.PriorityQueue
class那肯定是这样,那个模块里的class都是老式的
您调用 PriorityQueue.__init__
与此无关。
我有一个 python class 继承了优先级队列,我还使用描述符向 class 添加了一个属性,如下所示:
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__
函数。
为什么更改 superclass 会改变我的描述符的工作方式?是否与这一行有关:PriorityQueue.__init__(self)
?我怎样才能给 subclass 我想要的行为?
描述符仅适用于 新式 classes(直接或间接继承自 object
的那些)。在旧式 classes 上对描述符 __get__
方法有一些支持,但这种支持是有限的。
您正在使用的 PriorityQueue
class 可能不是从 object
继承的。如果是Queue.PriorityQueue
class那肯定是这样,那个模块里的class都是老式的
您调用 PriorityQueue.__init__
与此无关。