最好的情况是,我指的是 Python 方式和尽可能少的代码行。
我习惯像这样在 Python 中定义带有属性的类。
class MyClass(object):
def __init__(self):
self.value = 5
但是,我经常发现自己需要确保 self.value
只能采用特定类型的值。过去(来自 PHP OOP 背景)我使用类似于此的 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
以阻止其直接访问。
我最近发现(或正在发现)描述符。密切关注 excellent discussion here我写了一些看起来像这样的东西:
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
到底是什么?它是以某种方式绑定(bind)到 MyUsefulClass
类实例的 ValidatedAttribute 类实例吗?
其次,我真正喜欢的是,
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.
并以某种方式将属性访问绑定(bind)到某种拦截方法,而无需使用整个其他描述符类。
如果我的理解不够,我很抱歉 - 我仍在掌握新型 Python 类。任何正确方向的帮助或指示将不胜感激。
最佳答案
Firstly, what exactly is MyUsefulClass().a? Is it an instance of a ValidatedAttribute class somehow bound to an instance of a MyUsefulClass class?
是的,就是这样。
And secondly, what I'd really like is something like [...] and somehow bind an attribute access to some sort of intercept method, without having to use a whole other descriptor class.
好吧,您可以覆盖 __getattribute__
,因为它会拦截每个 属性查找,但它比使用描述符要复杂得多。
描述符正是您想要做的(自动验证)。您可以做的唯一改进是还使用元类自动为您设置 key ,然后您的类代码如下所示:
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]
关于python - 使用 Python 描述符 : How best to write a general validation getter-setter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18919961/