Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:多个属性,一个setter/getter_Python_Properties_Setter_Getter Setter - Fatal编程技术网

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

Python:多个属性,一个setter/getter,python,properties,setter,getter-setter,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...

考虑以下类定义

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
可能是你要找的
\uuuuu setattr\uuuuuuu(自我、名称、值)

看一看


就是这样。

我看到您的设置者只需记录一条消息,然后简单地分配值——事实上,您接受的答案只是分配值。你使用这种模式是因为它是其他语言中公认的实践/传统智慧,也许是一种名称以“J”开头的语言?如果是这样的话,那么请了解同样设计的Pythonic方法要简单得多:

class Of2010(object):
    def __init__(self):
        self.a = 1
        self.b = 2
        self.c = 3
没有什么都不做的设置程序,没有只为赋值而调用的中间函数。“什么?!”,你说?“公开暴露于成员变量?!!”嗯,事实上是的

从客户机代码的角度来看这些类。要使用您的类,客户端创建一个对象,然后使用以下命令分配属性“a”:

值得注意的是,这与我上面发布的5行程序类的代码完全相同

为什么J语言鼓励更详细的属性样式?在将来需求发生变化时保留类接口。如果在某个时间点,对象的某些其他值必须随着对的任何更改而更改,则必须实现属性机制。遗憾的是,J语言向客户机代码公开了属性访问机制的本质,因此在将来的某个时候引入属性是一项侵入性重构任务,需要重新构建使用该类及其“a”属性的所有客户机

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


因此,在Java中,我们从这个类(事实上,按照公认的实践,是所有类)的一开始就引入了这个属性复杂性权利,很有可能在将来某一天它会变得必要。有了Python,我们可以从实现可能工作的最简单的事情开始,即直接访问简单的成员变量,将复杂的方法留到将来实际需要并有价值的时候。因为那一天可能永远都不会到来,所以这是将代码的第一个工作版本推出的一个巨大飞跃。

它是属性(fset=…),但否则我会使用类似的东西。我希望在设置某个类的某些成员(实例)时发生一个操作。我希望对这些成员执行相同的操作(我的示例:打印成员的名称),而不复制其setter。这就是我需要二传手的原因。否则,正如你明智地指出的那样。我不会使用它们,因为它们在python中是不必要的。如果只需在每次调用时打印一个名称,为什么不将其编码到每个实例始终调用的父级uuu init_uu()中呢?这个建议已经过时了。根据“对于新样式的类,
\uuuuuu setattr\uuuuu
应该使用相同的名称调用基类方法,例如,
object.\uuuu setattr\uuuuuu(self,name,value)
”注意OP使用的是一个新样式的类。
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'))
class...
 def __setattr__(self, name, value):
  print 'setting', name
  self.__dict__[name] = value
class Of2010(object):
    def __init__(self):
        self.a = 1
        self.b = 2
        self.c = 3
obj = Of2010()
obj.a = 42