我在YouTube上观看了关于Python元编程的绝佳视频。我试着写了下面的代码(这几乎是从视频一样):多重继承如何在描述符中工作?
class Descriptor:
def __init__(self, name):
self.name = name
def __get__(self, instance, cls):
return instance.__dict__[self.name]
def __set__(self, instance, val):
instance.__dict__[self.name] = val
def __delete__(self, instance):
del instance.__dict__[self.name]
class Type(Descriptor):
ty = object
def __set__(self, instance, val):
if not isinstance(val, self.ty):
raise TypeError("%s should be of type %s" % (self.name, self.ty))
super().__set__(instance, val)
class String(Type):
ty = str
class Integer(Type):
ty = int
class Positive(Descriptor):
def __set__(self, instance, val):
if val <= 0:
raise ValueError("Must be > 0")
super().__set__(instance, val)
class PositiveInteger(Integer, Positive):
pass
class Person(metaclass=StructMeta):
_fields = ['name', 'gender', 'age']
name = String('name')
gender = String('gender')
age = PositiveInteger('age')
所以PositiveInteger
从Integer
和Positive
继承的,这两个类都定义做一些验证__get__
方法。我写了一些测试代码来说服自己,两种方法都可以运行:
class A:
def test(self):
self.a = 'OK'
class B:
def test(self):
self.b = 'OK'
class C(A, B):
pass
c = C()
c.test()
print(self.a)
print(self.b)
只发现只有第一个打印语句有效。第二个会引发一个AttributeError,这表明当名称冲突时,第一个基类将获胜。
所以我想知道为什么两个验证工作?更奇怪的是,当只有整数检查通过(例如person.age = -3)时,它的super().__set__(instance, val)
没有效果,使person.age保持不变。
感谢您的出色解释!我发布了自己的答案,并不知道有人已经回答了这个问题,直到我刷新了页面。 :) –