ban*_*ana 15 python setter properties 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)
Run Code Online (Sandbox Code Playgroud)
请注意set_[a|b|c]()
做同样的事情.有没有办法定义:
def set_magic(self,value):
print('setting <???>...')
self._??? = value
Run Code Online (Sandbox Code Playgroud)
一次,并将其用于a,b,c如下
a = property(fset=self.set_magic)
b = property(fset=self.set_magic)
c = property(fset=self.set_magic)
Run Code Online (Sandbox Code Playgroud)
Ign*_*ams 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'))
Run Code Online (Sandbox Code Playgroud)
我看到你的setter只记录一条消息然后只是分配值 - 实际上,你接受的答案只是赋值.你是否正在使用这种模式,因为它是其他语言中的接受实践/常规智慧,也许是以"J"开头的名字?如果是这样,那么请了解Pythonic对这种设计的方法要简单得多:
class Of2010(object):
def __init__(self):
self.a = 1
self.b = 2
self.c = 3
Run Code Online (Sandbox Code Playgroud)
没有do-nothing setter,没有中间函数调用只是为了赋值."你说的话?"公众接触成员变量?!!" 嗯,是的实际.
从客户端代码的角度来看这些类.要使用您的类,客户端创建一个对象,然后使用以下命令分配属性"a":
obj = Of2010()
obj.a = 42
Run Code Online (Sandbox Code Playgroud)
值得注意的是,这与我上面发布的5-liner类完全相同.
为什么J语言鼓励更冗长的财产风格?在将来更改需求时保留类接口.如果在某个时间点,对象的某些其他值必须随着对a的任何更改而改变,那么您必须实现属性机制.遗憾的是,J语言将属性访问机制的性质暴露给客户端代码,因此在将来的某个时刻引入属性是一种侵入性重构任务,需要重建使用该类的所有客户端和它的"一个"属性.
在Python中,情况并非如此.访问对象的"a"属性是在调用者的运行时确定的.由于直接访问和属性访问都"看起来"相同,因此即使实际机制不同,Python类也会保留此接口.重要的是,就客户端代码而言,它是完全相同的.
因此,在Java中,人们从这个类的开始(事实上,通过Accepted Practice,所有类)开始介绍这个属性的复杂性,以及将来某天可能需要它的可能性.使用Python,可以从实现可能工作的最简单的事情开始,也就是说,直接访问简单的成员变量,将复杂的方法留在将来实际需要额外的东西和价值的时间.由于那一天可能永远不会真正到来,所以这是将代码的第一个工作版本推出门的巨大进展.