python - 使用 python 描述符:如何最好地编写一般验证 getter setter

  显示原文与译文双语对照的内容
0 0

最好的是,我指的是Pythonically和尽可能少的代码行。

我习惯于在 python 中定义具有属性的类,如下所示。


class MyClass(object):

 def __init__(self):

 self.value = 5

然而,我经常发现自己需要确保 self.value 只能采用特定类型的值。 在过去的( 来自PHP面向对象背景) 中,我使用类似于下面这样的getter-setter方法:


 def value(self, new_value = -1)

 if new_value == -1:

 return self.value

 if isinstance(new_value, int) and new_value> -1:

 self.value = new_value

 else:

 raise TypeError

然后我使用 self.value() 访问 self.value,并将它的设置为 self.value(67) 。 通常我会将 self.value 命名为 self.__value,以阻止它的直接访问。

我最近发现了( 或者我正在寻找) 描述符。 我在这里写了一些看起来像这样的事情,以紧密的讨论 :


class ValidatedAttribute(object):

 def __init__(self, key, kind):

 self.key = key
 self.kind = kind

 def __get__(self, instance, owner):

 if self.key not in instance.__dict__:

 raise AttributeError, self.key

 return instance.__dict__[self.key]

 def __set__(self, instance, value):

 if not isinstance(value, self.kind):

 raise TypeError, self.kind

 instance.__dict__[self.key] = value 

class MyUsefulClass(object):

 a = ValidatedAttribute("a", int)

但我有几个问题 !

首先,MyUsefulClass().a 到底是什么? 它是ValidatedAttribute类的实例,它绑定到MyUsefulClass类的实例?

其次,我想要的是


class MyUsefulClass(object):

 def __init__(self):

 self.value = Checker(int, 99)

 def Checker(self, kind, default):

 # Code for verifying that associated attribute is of type kind.

并且将属性访问绑定到某种拦截方法,而不必使用整个描述符类。

如果我的理解不足,我很抱歉- 我仍然在使用新样式 python 类。 在正确的方向上,任何帮助或者指针都会。

时间: 原作者:

0 0

首先,MyUsefulClass ( ) 究竟是什么? 它是ValidatedAttribute类的实例,它绑定到MyUsefulClass类的实例?

是的,就是这样。

它的次,我想要的是类似于 [...],并且将属性访问绑定到某种拦截方法,而不必使用整个描述符类。

嗯,你可以覆盖 __getattribute__,因为它在每次属性查找时都能进行 ,但是比使用描述符更复杂。

描述符正确的工作,你想要做的是( 自动验证) 。 关于唯一的改进,你也可以使用元类自动为你设置密钥,然后类代码如下:


class MyUsefulClass(object):

 a = ValidatedAttribute(int)

但是首先要熟悉描述符,元类很复杂,难以理解。

哦,我对你的ValidatedAttribute 做了一个小小的改动:


def __init__(self, key, default):

 self.key = key
 self.kind = type(default)
 self.default = default

def __get__(self, instance, owner):
 if self.key not in instance.__dict__:
 return self.default
 return instance.__dict__[self.key]

原作者:
0 0

听起来你想使用属性


class MyUsefulClass(object):

 def __init__(self):
 self._value = 0

 @property
 def value(self):
 return self._value

 @value.setter
 def value(self, value):
 self._value = self.Checker(value, int, 99)

 def Checker(self, value, kind, default):
 return value if isinstance(value, kind) else default

原作者:
0 0

请不要这样做,不要做 isinstance(new_value, int)

你可能会 get get


from numbers import Integral
isinstance(new_value, Integral)

但是duck打字是完全anathema的。

首先,MyUsefulClass ( ) 究竟是什么? 它是ValidatedAttribute类的实例,它绑定到MyUsefulClass类的实例?

为了找到 MyUsefulClass().a,python 请求类。 类告诉它它拥有属性的getter-setter,并告诉 python 请求属性。 属性表示找到它,然后告诉类属性是什么。 属性不是getter设置器。

MyUsefulClass.a 是 getter-setter ( 属性),而不是 MyUsefulClass().a

其次,我真正喜欢的是 [stuff ]

因这里,你只能在类上设置属性,而不是在实例上设置属性,因为如何检索属性或者项。

原作者:
...