【问题标题】:Set a Python property using a function call使用函数调用设置 Python 属性
【发布时间】:2014-06-18 10:47:05
【问题描述】:

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

【问题讨论】:

    标签: python python-2.7 properties setter


    【解决方案1】:

    您可以使用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')))
    

    【讨论】:

      【解决方案2】:

      @MartijnPieters 的回答是如果可能的话,但如果您需要尝试动态派生设置器,您也可以直接访问类上的属性描述符,将实例作为参数提供。

      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))
      

      【讨论】:

      • 有趣。对于我的具体情况,我不需要得到这个通用的,但我不知道这样的事情是可能的。
      猜你喜欢
      • 2011-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多