documentation on __slots__
表示他们已作为描述符实施。"是否可以为通过__slots__
创建的描述符自定义getter / setter?我可以做点什么吗
class Foo(object):
__slots__ = ['a']
def __init__(self, a):
self._a = a
@property
def a(self):
return self._a.title()
@a.setter
def a(self, x):
if len(x) == 10:
self._a = x
else:
raise ValueError('incorrect length!')
@a.deleter
def a(self):
self._a = ''
ETA:只有半相关,上面的self._a = a
位意味着a
的初始值不会通过setter运行。有没有办法将值传递到__init__
上的setter?
ETA2:基于Bi Rico's answer,我得出了这个:
class Foo(object):
__slots__ = ('_a',)
def __init__(self, x):
self._a = self.validate_a(x)
@staticmethod
def validate_a(x):
if x % 2 == 0:
return x
else:
raise ValueError(':(')
@property
def a(self):
return str(self._a)
@a.setter
def a(self, x):
self._a = self.validate(x)
@a.deleter
def a(self):
self._a = 0
单独的validate_a
方法解决了我的附加功能'关于处理传递到__init__
的价值的问题与通过设定者传递的价值相同(如果你不想这样做,那么这是不必要的。)
只有把“假”放在一边才会感觉有点蠢蠢欲动。 __slots__
中的var名称(即Foo._a
仅为了Foo.a
属性的利益而存在),但它有效。
答案 0 :(得分:0)
您不需要仅在__slots__
属性中列出属性,如果您将广告位更改为__slots__ = ['_a']
,您的课程将按预期工作。
抱歉,我在第一次阅读时没有看到你的附加问题。使用静态验证方法很好,但您不需要在__init__
中明确调用它,而是直接设置self.a
,只在您有意使用时self._a
绕过setter / getter。
我不知道你的意思,
只有把“假”放在一边才会感觉有点蠢蠢欲动。
中的var名称__slots__
a
是该类的一个属性(btw也是使用描述符实现的)所以如果你还将它包含在__slots__
中,你指示该类为它创建两个冲突的描述符同样的事情。
_a
是该类的一个属性,因此,如果您使用__slots__
,则必须。仅仅因为_a
以下划线开头并没有使它比任何其他属性更好或更差,我会称之为"受保护"属性而不是虚拟属性:)。你确定你想要使用__slots__
,这似乎是最好的" hacky"这件事的一部分。
答案 1 :(得分:0)
您的代码几乎按原样运行;你需要做的唯一改变是
__slots__ = ['_a'] # _a instead of a
def __init__(self, a):
self.a = a # a instead of _a
如果由于某种原因你真的想避免单独的_a
槽和a
包装器,你可以用你自己的描述符替换默认的槽描述符,但我不推荐它。此外,替换必须在创建类之后发生:
class Foo(object):
__slots__ = ['a']
underlying_descriptor = Foo.a
@property
def a(self):
return underlying_descriptor.__get__(self, Foo).title()
@a.setter
def a(self, x):
if len(x) == 10:
underlying_descriptor.__set__(self, x)
else:
raise ValueError('incorrect length!')
@a.deleter
def a(self):
underlying_descriptor.__del__(self)
Foo.a = a
您可以尝试通过设置underlying_descriptor
并通过Foo._a = Foo.a
访问self._a
来简化所有_a
内容,但是您的对象上有(https?:\/\/)?(www\.)?[a-z0-9-]+\.(com|org)(\.[a-z]{2,3})?
属性,这个版本的重点是避免第二个属性。