Python替代dict风格的二传手? [英] Pythonic alternative to dict-style setter?

查看:88
本文介绍了Python替代dict风格的二传手?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

人们倾向于认为getter和setter是非Python语言的,而是倾向于使用 @property .我目前正在尝试扩展使用 @property 来支持字典的类的功能:

People tend to consider getters and setters un-Pythonic, prefering to use @property instead. I'm currently trying to extend the functionality of a class that uses @property to support a dict:

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函数会容易得多.但是,有没有一种更Python化的方法来进行这种重构?

Of course, I could create some helper classes to deal with this, but it seems like just writing setter/getter functions that take a key and value would be much simpler. But is there a more Pythonic way to do this refactor?

推荐答案

您所描述的不是属性的情况.这些属性用于允许 obj (或更确切地说,其类)自定义 obj.prop = value 的行为.如果您要自定义 obj.prop [key] =值,则需要处理的不是 obj ,而是 obj.prop ,这意味着您需要将 obj.prop 设为自定义类.您想要在这里创建一个带有 __ setitem __ 的自定义类.

What you describe is not a case for properties. Properties are for allowing obj (or rather, its class) to customize the behavior of obj.prop = value. If you want to customize obj.prop[key] = value, then you need to handle that not in obj but in obj.prop, which means you need to make obj.prop be a custom class. What you want here is to create a custom class with a __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().

Then in your MyClass's __init__, do self.foo = Foo().

如果您想让类似dict的对象知道其父对象是什么(例如,由于副作用应发生在父对象上,则将父对象作为参数传递给Foo:

If you want this dict-like object to know what its parent object is (e.g., because the side effect should take place on the parent, then pass the parent as an argument to 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).

关于吸气剂/吸气剂,您正在做的不是典型的吸气剂/吸气剂.不鼓励使用的是诸如 getSomeProp() setSomeProp(value)之类的东西,其中为您获取/设置的每个属性都有一个单独的方法.在您的示例中,您描述的是不同的东西,这是用于设置键值对的通用get/set机制(可能对对象的行为具有某种意义).拥有方法 setPair(key,value)并不比拥有名为 doSomething(arg1,arg2)的方法更糟糕.这里有一个额外的参数,因此您的任务不适合 obj.key = value 的简单模式.如果希望 obj.prop [key] =值中的键/值了解" obj ,则还需要一个间接层.在像 obj.prop [key] = value 这样的赋值中,键和值是从 obj 中删除的一步,并且只能直接与 prop 进行交互

With regard to getters/setters, what you're doing is not a typical getter/setter. The kind of thing that is discouraged is things like getSomeProp() and setSomeProp(value), where there is a separate method for each property that you get/set. In your example, you're describing something different, which is a generalized get/set mechanism for setting key-value pairs (which presumably have some meaning for the object's behavior). Having a method setPair(key, value) is not any worse than having a method called doSomething(arg1, arg2). Here you have an extra parameter, so your task doesn't fit into the simple pattern of obj.key = value. You also have an extra layer of indirection if you want the key/value inobj.prop[key] = value to "know about" obj; in an assignment like obj.prop[key] = value, the key and value are one step removed from obj and interact directly only with prop.

您也可以使用John Smith Optional建议的简单方法来完成此操作.您是要这样做还是要像我描述的那样使用自定义对象,取决于您希望API的设置方式.将代码围绕自定义数据保存"类(如我在此处概述的类)构建可能会带来可读性的好处,但这确实使实现变得更加复杂.

You could also do it with a simple method as John Smith Optional suggests. Whether you want to do it that way or with a custom object like I described depends on how you want the API set up. There can be readability benefits to having the code built around custom "data-holding" classes like the one I outlined here, but it does make the implementation a bit more complex.

这篇关于Python替代dict风格的二传手?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆