python - 具有 Python 属性的属性映射

标签 python

有没有办法让 Python @property 同时充当 setter 和 getter?

我觉得我以前在哪里见过这个,但不记得也无法自己重新创建解决方案。

例如,代替:

class A(object):
  def __init__(self, b): self.b = b
  def get_c(self): return self.b.c
  def set_c(self, value): self.b.c = value
  c = property(get_c, set_c)

我们可以以某种方式表示对于 A 对象,c 属性实际上等同于 b.c 的 getter、setter(和删除器,如果我们喜欢)。

动机:

当我们需要 A 作为 B 对象(其中 b 是一个实例)的代理包装器时,这将特别有用但是仅共享数据属性,不共享方法。诸如此类的属性将允许 AB 对象的数据在同一代码使用时保持完全同步。

最佳答案

我想你在找this forwardTo class正如在 ActiveState 上发布的那样。

This recipe lets you transparently forward attribute access to another object in your class. This way, you can expose functionality from some member of your class instance directly, e.g. foo.baz() instead of foo.bar.baz().

class forwardTo(object):
    """
    A descriptor based recipe that makes it possible to write shorthands
    that forward attribute access from one object onto another.

    >>> class C(object):
    ...     def __init__(self):
    ...         class CC(object):
    ...             def xx(self, extra):
    ...                 return 100 + extra
    ...             foo = 42
    ...         self.cc = CC()
    ...
    ...     localcc = forwardTo('cc', 'xx')
    ...     localfoo = forwardTo('cc', 'foo')
    ...
    >>> print C().localcc(10)
    110
    >>> print C().localfoo
    42

    Arguments: objectName - name of the attribute containing the second object.
               attrName - name of the attribute in the second object.
    Returns:   An object that will forward any calls as described above.
    """
    def __init__(self, objectName, attrName):
        self.objectName = objectName
        self.attrName = attrName
    def __get__(self, instance, owner=None):
        return getattr(getattr(instance, self.objectName), self.attrName)
    def __set__(self, instance, value):
        setattr(getattr(instance, self.objectName), self.attrName, value)
    def __delete__(self, instance):
        delattr(getattr(instance, self.objectName), self.attrName)

为了获得更健壮的代码,您可能需要考虑将 getattr(instance, self.objectName) 替换为 operator.attrgetter(self.objectName)(instance)。这将允许 objectName 成为带点的名称(例如,您可以让 A.c 成为 A.x.y.z.d 的代理)。

关于python - 具有 Python 属性的属性映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14167675/

相关文章:

python - 惰性评估是如何实现的(例如在 ORM 中)

python - 如何使用列表重命名 Pandas 中的列

Python如何将类的副本分配给变量? (而不是通过引用)

python - 机械化._response.httperror_seek_wrapper : HTTP Error 404: Not Found

python - 生成总和为参数 N 的列表的乘积

python - 在 python 中组合列表中的第一个元素和同一列表的其他元素

python - 值错误 : unknown is not supported in sklearn. RFECV

python - 幸运数字八 - Hackerrank-W28

python - 连接到两个数据库

python - 如何导入自己的模块进行模拟? (导入错误 : no module named my_module!)