【问题标题】:Pythonic alternative to dict-style setter?dict-style setter 的 Pythonic 替代品?
【发布时间】:2014-04-06 22:43:51
【问题描述】:

人们倾向于认为 getter 和 setter 不是 Pythonic,而是更喜欢使用 @property。我目前正在尝试扩展使用@property 来支持字典的类的功能:

class OldMyClass(object):
    @property
    def foo(self):
       return self._foo

    @foo.setter
    def foo(self, value):
        self.side_effect(value)
        self._foo = value

class NewMyClass(object):
    @property
    def foo(self, key):  # Invalid Python
        return self._foo[key]

    @foo.setter
    def foo(self, key, value):  # Invalid Python
        self.side_effect(key, value)
        self._foo[key] = value

当然,我可以创建一些帮助类来处理这个问题,但似乎只编写带有键和值的 setter/getter 函数会简单得多。但是有没有更 Pythonic 的方式来进行这种重构?

【问题讨论】:

  • 我不太明白你的问题。 foo.setter 是什么?通常,这只有在您之前已经定义了一个名为foo 的getter 时才有效。另外,您打算如何使用生成的对象? key 应该如何使用?
  • 是的,我没有包括吸气剂,因为我认为它并不真正相关。为了清楚起见,我将添加它。我不明白你关于我打算如何使用结果对象的问题
  • 我的意思是,您打算使用什么代码来设置键/值?对于普通属性,您可以使用obj.prop = value。你想做什么呢?
  • 理想情况下我想做 obj.prop[key]=value
  • 那你为什么需要一个属性呢?把prop做成普通字典就好了。

标签: python coding-style setter getter getter-setter


【解决方案1】:

您所描述的不是属性的情况。属性用于允许obj(或者更确切地说,它的类)自定义obj.prop = value 的行为。如果你想自定义obj.prop[key] = value,那么你需要处理的不是obj,而是obj.prop,这意味着你需要让obj.prop成为一个自定义类。您想要在这里创建一个带有__setitem__ 的自定义类。

class Foo(object):
    def __init__(self):
        self._vals = {}

    def __setitem__(self, key, val):
        do_side_effect(key, val)
        self._vals[key] = val

然后在你的 MyClass 的__init__ 中,执行self.foo = Foo()

如果你想让这个类似dict的对象知道它的父对象是什么(例如,因为副作用应该发生在父对象上,那么将父对象作为参数传递给Foo:

class Foo(object):
    def __init__(self, parent):
        self.parent = parent
        self._vals = {}

    def __setitem__(self, key, val):
        parent.do_side_effect(key, val)
        self._vals[key] = val

然后在MyClass.__init__ 你做self.foo = Foo(self)

关于 getter/setter,您所做的不是典型的 getter/setter。不鼓励使用 getSomeProp()setSomeProp(value) 之类的东西,其中您获取/设置的每个属性都有一个单独的方法。在您的示例中,您正在描述一些不同的东西,这是一种用于设置键值对的通用获取/设置机制(这可能对对象的行为具有一定的意义)。拥有一个方法setPair(key, value) 并不比拥有一个名为doSomething(arg1, arg2) 的方法差。这里你有一个额外的参数,所以你的任务不适合obj.key = value 的简单模式。如果您希望obj.prop[key] = value 中的键/值“了解”obj,您还需要额外的间接层;在像obj.prop[key] = value 这样的分配中,键和值是从obj 中删除的一步,并且只与prop 直接交互。

您也可以使用 John Smith Optional 建议的简单方法。无论您是想这样做还是像我描述的那样使用自定义对象,都取决于您希望如何设置 API。围绕我在此处概述的自定义“数据保存”类构建代码可以带来可读性优势,但它确实使实现更加复杂。

【讨论】:

    最近更新 更多