2013-04-27 94 views
1

更改两个属性值,我有两个属性,当我为foo设置一个新值的一类,我想的是值的bar 也随之变化,这样我就可以像去这样的:的属性setter命名惯例,在蟒蛇

class MyClass(object): 

    _foo = '' 
    _bar = '' 

    @property 
    def foo(self): 
    return self._foo 

    @foo.setter 
    def foo(self, foo): 
    self._foo = foo.lower() 
    self._bar = foo.upper() 

    @property 
    def bar(self): 
    return self._bar 

我不想反映的方式,当我改变bar foo变化的价值,所以我没有实现的setter为bar在其他方向上的变化。

阅读关于干净的代码实践我发现这是一个很好的习惯,根据它们的具体名称命名你的方法,所以我认为,不要使用上面的语法,我可以使用这个定义,似乎更自我解释:

def set_foo_and_bar(self, foo): 
    self._foo = foo.lower() 
    self._bar = foo.upper() 

现在的问题是,我失去了Python的语法object.property。我真的认为这是一个虚拟问题,但我想知道如何处理这种依赖操作的定义,我应该使用第一种语法还是第二种语法?如果setter方法更改状态更剧烈,说更改更多的属性?,我应该使用注释来说明这两个属性之间存在依赖关系吗?或者让客户发现他自己的'魔术'行为?

+2

使用占位符名称*,当然*不明显。但在真实的代码中,我会假设任何不明确的情况都来自错误的命名。例如,假设一个GUI小部件的整型属性'width'和'right_border'。现在不是很奇怪,是吗? – delnan 2013-04-27 15:16:36

+0

@delnan与你的小部件示例很明显,属性是依赖的,比如说我改变了宽度,所以尺寸也发生了变化,但是对于语义上不太接近的属性,我认为如果我不是那么'心智映射'明确的定义。 – Twissell 2013-04-27 15:23:34

+0

请举个例子。正如我所说的,我只能想象这个问题来自不明名字或其他东西。或者也许属性*不应该相互影响。 – delnan 2013-04-27 15:25:33

回答

0

我意识到这是一个老问题,但似乎答案很简单。 foo.setter装饰器返回一个新的property对象,装饰函数作为该属性的设置器,装饰器语法意味着此返回值存储在函数的位置。因此,如果您希望foo属性正常工作,则还需要命名装饰函数foo。如果您使用不同的函数名称,则无法使用装饰器语法,否则将会损坏属性。

如果有有意义的变量名是对你至关重要,你应该手动应用property你的getter和setter方法:

class MyClass(object): 

    _foo = '' 
    _bar = '' 

    def _get_foo(self): 
    return self._foo 

    def _set_foo_and_bar(self, foo): 
    self._foo = foo.lower() 
    self._bar = foo.upper() 

    foo = property(_get_foo, _set_foo_and_bar) 

    @property 
    def bar(self): 
    return self._bar 

这似乎并没有给我非常有用。我总是喜欢装饰器的语法,除非有紧迫的理由不这样做。问题中的代码完美地完成了任务。