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

发布于 2024-08-18 17:27:12 字数 815 浏览 3 评论 0原文

考虑以下类定义,

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)

Consider the following class definitions

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)

note that set_[a|b|c]() do the same thing. is there a way do define:

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

once and use it for a,b,c as follows

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

涙—继续流 2024-08-25 17:27:12
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'))
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'))
‖放下 2024-08-25 17:27:12

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

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

没有什么都不做的设置器,没有中间函数调用只是为了分配一个值。 “你说的话? “公开暴露成员变量?!!”嗯,实际上是的

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

obj = Of2010()
obj.a = 42

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

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

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

因此,在 Java 中,人们从此类(事实上,根据所有类的公认实践)一开始就引入了这种属性复杂性,以防有一天它可能变得必要。未来。使用Python,我们可以从实现可能可行的最简单的事情开始,即直接访问简单的成员变量,将复杂的方法留给将来实际需要且有价值的额外内容。由于这一天可能永远不会真正到来,因此在发布代码的第一个工作版本方面这是一个巨大的进步。

I see that your setters just log a message and then simply assign the value - in fact, your accepted answer just assigns the value. Are you using this pattern because it is the Accepted Practice / Conventional Wisdom in some other language, perhaps one whose name starts with "J"? If so, then please learn that the Pythonic approach to this same design is the much simpler:

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

No do-nothing setters, no intermediate function calls just to assign a value. "What?!", you say? "Public exposure to member variables?!!" Well, yes actually.

Look at these classes from the standpoint of client code. To use your class, clients create an object, and then assign property "a" using:

obj = Of2010()
obj.a = 42

Remarkably, this is the exact same code for the 5-liner class I posted above.

Why does the J-language encourage the more verbose property style? To preserve the class interface in the event of future change in requirements. If at some point in time, some other value of the object must change in concert with any changes to a, then you must implement the property mechanism. Sadly, the J-language exposes the nature of the attribute access mechanism to the client code, so that to introduce a property at some point in the future is an intrusive refactoring task that will require a rebuild of all clients that make use of that class and its "a" attribute.

In Python, such is not the case. Access to the object's "a" attribute is determined at runtime in the caller. Since direct access and property access both "look" the same, your Python class preserves this interface even though the actual mechanism is different. What matters is that it is identical as far as the client code is concerned.

So in Java, one introduces this property complexity right from the inception of this class (and in fact, by Accepted Practice, of all classes), on the off-chance that it may become necessary some day in the future. With Python, one can start by implementing the Simplest Thing That Could Possibly Work, that is, direct access to simple member variables, leaving the complex approach for the time in the future that the extra stuff is actually required and of value. Since that day may never actually come, this is a huge jump forward in getting that first working version of your code out the door.

苏别ゝ 2024-08-25 17:27:12

也许你正在寻找
__setattr__(self, name, value)

看看

May be you're looking for
__setattr__(self, name, value)

Take a look here

指尖凝香 2024-08-25 17:27:12
class...
 def __setattr__(self, name, value):
  print 'setting', name
  self.__dict__[name] = value

就是这样。

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

That's it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文