使用函数调用设置Python属性

时间:2014-05-01 20:57:11

标签: python python-2.7 properties setter

有没有办法在Python中使用函数调用而不是" a.x = value"来设置属性?语法?

说明:   有一节课,我没有写。我必须从这个类中查询和设置各种数据。大多数项目都有setter和getter函数,比如getA()和setA(value)。但是一些项目已被宣布为属性。我有一些代码,我得到各种项目的setter函数,以便我可以循环它们。但它不适用于属性,因为没有setter函数。

class DataObject(object):
    def __init__(self, data, setterFunc):
        super(DataObject, self).__init__()
        self._data = data
        self._setterFunc = setterFunc

    @property
    def data(self):
        return self._data

    @data.setter
    def data(self, value):
        if self._setterFunc:
            self._data = value
            self._setterFunc(value)

foo = SomeClassIDidNotWrite()
objectList = []
objectList.append(DataObject(foo.getA(), foo.setA))
objectList.append(DataObject(foo.getB(), foo.setB))
# objectList.append(DataObject(foo.c, foo.c))   <-- This does not work

for dataObj in objectList:
    dataObj.data = 5

2 个答案:

答案 0 :(得分:3)

您可以使用setattr()功能动态设置属性;这适用于属于真正属性的属性。

您可以使用lambda功能或使用functools.partial()创建 setter

objectList.append(DataObject(foo.c, lambda val: setattr(foo, 'c', val)))

from functools import partial

objectList.append(DataObject(foo.c, partial(setattr, foo, 'c')))

答案 1 :(得分:1)

@MartijnPieters答案是可行的方法,但如果您需要尝试动态派生setter,您还可以直接访问该类的属性描述符,并将该实例作为参数。

foo = SomeClassIDidNotWrite()
SomeClassIDidNotWrite.a.fset(foo, val)

甚至更动态:

attr_name = 'a'
getattr(foo.__class__, attr_name).fset(foo, val)

将此与您现有的get / set代码相结合并将其包装在try / except中,您可以为需要使用的所有属性创建通用处理程序。

for attr_name in ('A', 'B', 'C'):
    try:
        getter = getattr(foo, 'get' + attr_name)
        setter = getattr(foo, 'set' + attr_name)
    except AttributeError:
        descriptor = getattr(foo.__class__, attr_name)
        getter = functools.partial(descriptor.fget, foo)
        setter = functools.partial(descriptor.fset, foo)
    objectList.append(DataObject(getter, setter))