有没有办法在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
答案 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))