我创建了一个自定义描述符,并将其分配给类中的一个值。但是,我想在不使用描述符的情况下最初设置实例变量
__set__
方法。
class Descriptor:
def __set_name__(self, owner, name):
self.private_name = '_' + name
def __get__(self, instance, owner=None):
if instance is None:
return self
return getattr(instance, self.private_name)
def __set__(self, instance, value):
if value == 'bye':
raise ValueError('blah')
self.toggle(instance)
setattr(instance, self.private_name, value)
@staticmethod
def toggle(instance):
pass
class Foo:
bar = Descriptor()
def __init__(self, bar):
# no need to call descriptor initially for some reason ok? but is still called (unnecessary)
self.bar = bar
foo = Foo('hi')
foo.bar = 'bye' # descriptor needed here and with every subsequent change to bar.
有没有办法解决这个问题并设置
self.bar
直接?
我有这个问题,因为我最初使用
@property
描述符,使用时允许调用描述符方法和私有变量,这正是我所需要的。自从
@财产
是一个描述符,必须有一种合理的方法来做到这一点(尽管这与
@财产
私有变量是在类的范围内定义的,而不是像自定义描述符那样定义描述符类,自定义描述符允许在类内修改两者,但只有类范围外的公共版本(我知道私有变量不是真正的私有变量,但这无关紧要)。)
例如,使用@property的相同代码:
class Foo:
def __init__(self, bar):
# no need to call setter initially
self._bar = bar
@property
def bar(self):
return self._bar
@bar.setter
def bar(self, value):
self._bar = value
foo = Foo('hi')
foo.bar = 'bye' # property setter called.
然而,在这种情况下,当引入更多的实例变量时,getter和setter会占用更多的空间
toggle
对于添加的每个新的setter,必须重写原始装饰器的方法(这就是为什么我将@properties重写为自定义描述符类的原因,因为它似乎是一个使用oop的地方,不必重复自己)。