可以给Python属性添加参数以减少代码重复吗?

4 投票
3 回答
4546 浏览
提问于 2025-04-15 14:04

我有一个这样的类:


class Vector(object):
    def __init__(self, x=0, y=0, z=0):
        self.x = x
        self.y = y
        self.z = z

    def _getx(self):
        return self._x
    def _setx(self, value):
        self._x = float(value)
    x = property(_getx, _setx)

    def _gety(self):
        return self._y
    def _sety(self, value):
        self._y = float(value)
    y = property(_gety, _sety)

    def _getz(self):
        return self._z
    def _setz(self, value):
        self._z = float(value)
    z = property(_getz, _setz)

这三个获取器和设置器的内容都是一样的,唯一不同的是它们所修改的对象属性(x、y、z)。有没有办法让我只写一个获取器和一个设置器,然后传入要修改的变量,这样就不用重复写代码了?

3 个回答

0

虽然没有测试过,但这个应该可以用:

def force_float(name):
    def get(self):
        return getattr(self, name)
    def set(self, x):
        setattr(self, name, float(x))
    return property(get, set)

class Vector(object):
    x = force_float("_x")
    y = force_float("_y")
    # etc
2

为什么不直接写这个呢?

class Vector(object):
    def __init__(self, x=0, y=0, z=0):
        self.x = x
        self.y = y
        self.z = z

如果你的获取器(getter)和设置器(setter)是从像Java这样的语言中延续过来的话,那就别写它们了。直接把属性x、y和z暴露出来就行。如果以后需要的话,可以再把它们改成属性,而且和Java不同的是(Java需要重新编译),所有的客户端代码依然可以正常工作。

关于Python中的获取器和设置器,大家普遍的看法是“等到需要的时候再写”。只有在它们能真正为你的程序带来价值的时候(比如保护内部数据结构),才写获取器和设置器。否则,就不需要写,花时间去做真正有生产力的编码吧。

16

当然,可以根据这份文档中清楚解释的概念,制作一个自定义的描述符:

class JonProperty(object):
    def __init__(self, name):
        self.name = name

    def __get__(self, obj, objtype):
        return getattr(obj, self.name)

    def __set__(self, obj, val):
        setattr(obj, self.name, float(val))

然后就可以直接使用它了:

class Vector(object):
    def __init__(self, x=0, y=0, z=0):
        self.x = x
        self.y = y
        self.z = z
    x = JonProperty('_x')
    y = JonProperty('_y')
    z = JonProperty('_z')

撰写回答