目前,当我想要定义一个setter并单独留下getter时,我会这样做:
@property
def my_property(self):
return self._my_property
@my_property.setter
def my_property(self, value):
value.do_some_magic()
self._my_property = value
有没有办法缩短它?我想跳过这部分,因为它总是看起来一样:
@property
def my_property(self):
return self._my_property
答案 0 :(得分:6)
没有开箱即用的解决方案,但你可以尝试这样的事情:
def defprop(name):
def getter(self):
return getattr(self, name)
return property(getter)
class C(object):
# ...
my_dictionary = defprop('_my_dictionary')
# ...
虽然这不会为您节省很多次击键,但仍需要复制属性名称。除此之外它不那么明确。
更新:经过一番思考,我已经提出了这种基于描述符的黑客技巧(免责声明:这只是为了演示,我并不暗示它和#39;除非你有充分的理由这样做,否则这是一种很好的做法):
class with_default_getter(object):
def __init__(self, func):
self._attr_name = '_{0.__name__}'.format(func)
self._setter = func
def __get__(self, obj, type):
return getattr(obj, self._attr_name)
def __set__(self, obj, value):
return self._setter(obj, value)
用法:
class C(object):
@with_default_getter
def my_property(self, value):
print 'setting %s'
self._my_property = value
>>> c = C()
>>> c.my_property = 123
setting 123
>>> c.my_property
123
这与@georg建议的几乎相同,只是将实现展开到描述符。
答案 1 :(得分:5)
您可以按照下划线约定制作一个自动创建getter的装饰器:
def setter(fn):
def _get(self):
return getattr(self, '_' + fn.__name__)
def _set(self, val):
return fn(self, val)
return property(_get, _set)
或更简洁,如果您更喜欢这种风格:
def setter(fn):
return property(
lambda self: getattr(self, '_' + fn.__name__),
fn)
用法:
class X(object):
@setter
def my_property(self, value):
self._my_property = value + 1
x = X()
x.my_property = 42
print x.my_property # 43
答案 2 :(得分:1)
没有我所知道的捷径 - 记住显式优于隐式(来自蟒蛇的Zen)。
可能在你的代码到目前为止,属性总是那样 - 但你可以在某个时候写一个属性getter来取一个完全计算的值 - 在这种情况下你的属性getter和setter看起来不像那样所有
如果您愿意,可以写一个包装器,它可以将这些简单的默认方法作为包装器的一部分提供。
答案 3 :(得分:1)
def set_my_property(self, value):
value.do_some_magic()
self._my_property = value
my_property = property(fset=set_my_property)