Python:多个属性,一个setter / getter

时间:2010-01-23 15:08:35

标签: python properties setter getter-setter

考虑以下类定义

class of2010(object):
    def __init__(self):
        self._a = 1
        self._b = 2
        self._c = 3

    def set_a(self,value):
        print('setting a...')
        self._a = value
    def set_b(self,value):
        print('setting b...')
        self._b = value
    def set_c(self,value):
        print('setting c...')
        self._c = value
    a = property(fset=self.set_a)
    b = property(fset=self.set_b)
    c = property(fset=self.set_c)

请注意set_[a|b|c]()做同样的事情。有没有办法定义:

def set_magic(self,value):
    print('setting <???>...')
    self._??? = value

一次并将其用于a,b,c如下

a = property(fset=self.set_magic)
b = property(fset=self.set_magic)
c = property(fset=self.set_magic)

4 个答案:

答案 0 :(得分:20)

def attrsetter(attr):
  def set_any(self, value):
    setattr(self, attr, value)
  return set_any

a = property(fset=attrsetter('_a'))
b = property(fset=attrsetter('_b'))
c = property(fset=attrsetter('_c'))

答案 1 :(得分:5)

我看到你的setter只记录一条消息,然后只是分配值 - 事实上,你接受的答案只是分配值。你是否正在使用这种模式,因为它是其他语言中的接受实践/常规智慧,也许是以“J”开头的名字?如果是这样,那么请了解Pythonic对这种设计的方法要简单得多:

class Of2010(object):
    def __init__(self):
        self.a = 1
        self.b = 2
        self.c = 3

没有do-nothing setter,没有中间函数调用只是为了赋值。 “你说的话? “公众接触成员变量?!!”好吧,实际上

从客户端代码的角度来看这些类。要使用您的类,客户端创建一个对象,然后使用:

分配属性“a”
obj = Of2010()
obj.a = 42

值得注意的是,这与我上面发布的5-liner类完全相同。

为什么J语言鼓励更冗长的财产风格?在将来更改需求时保留类接口。如果在某个时间点,对象的某些其他值必须随着对a的任何更改而改变,那么您必须实现属性机制。遗憾的是,J语言将属性访问机制的性质暴露给客户端代码,因此在将来的某个时刻引入属性是一种侵入性重构任务,需要重建使用该类的所有客户端和它的“一个”属性。

在Python中,情况并非如此。访问对象的“a”属性是在调用者的运行时确定的。由于直接访问和属性访问都“看起来”相同,因此即使实际机制不同,Python类也会保留此接口。重要的是,就客户端代码而言,它是完全相同的。

所以在Java中,人们从这个类的开始(事实上,通过Accepted Practice,所有类)开始介绍这个属性的复杂性,因为它很可能是必要的。将来的某一天。使用Python,可以从实现可能工作的最简单的事情开始,也就是说,直接访问简单的成员变量,将复杂的方法留在将来实际需要额外的东西和价值的时间。由于那一天可能永远不会真正到来,所以这是将代码的第一个工作版本推出门的巨大进展。

答案 2 :(得分:2)

class...
 def __setattr__(self, name, value):
  print 'setting', name
  self.__dict__[name] = value

就是这样。

答案 3 :(得分:1)

可能你正在寻找 __setattr__(self, name, value)

看看here