【问题标题】:Python: property setter with numpy arraysPython:带有 numpy 数组的属性设置器
【发布时间】:2021-12-17 16:40:45
【问题描述】:

让我们考虑以下示例:

point.py

import numpy as np

class Point:
    def __init__(self):
        self._x = np.array([])
        self._y = np.array([])
    
    @property
    def x(self) -> np.ndarray:
        return self._x

    @x.setter
    def x(self, value: Union[float, list, np.ndarray]):
        self._x = np.atleast_1d(value)

    @property
    def y(self) -> np.ndarray:
        return self._y

    @y.setter
    def y(self, value: Union[float, list, np.ndarray]):
        self._y = np.atleast_1d(value)

现在,如果我执行以下操作:

from point import Point

coordinates = Point()
coordinates.x = [0, 5]
coordinates.x[0] = 3

当我分配列表时,x.setter 会被调用,但在我修改数组元素时不会调用。

如何更新我的代码以触发两者中的设置器?

非常感谢!

【问题讨论】:

  • 你真的需要那个:coordinates.x[0] = 3真的更新coordinates._x吗?使用coordinates.x[0] = ...,您不会触发__set__,只有描述符的__get__,因为[0] 指的是“x 的方法”。
  • 显示每个作业的结果,并说出问题所在。

标签: python python-3.x numpy properties


【解决方案1】:
In [29]: p = Point()
In [30]: x
Out[30]: array([0., 0., 0.])
In [31]: p.x
Out[31]: array([], dtype=float64)
In [32]: p.y
Out[32]: array([], dtype=float64)
In [33]: p.x = [0,5]
In [34]: p.x
Out[34]: array([0, 5])

元素分配按预期工作(至少对我来说是合理的):

In [35]: p.x[0]
Out[35]: 0
In [36]: p.x[0]=10
In [37]: p.x
Out[37]: array([10,  5])
In [38]: p._x
Out[38]: array([10,  5])

我不太确定你的问题是什么。是关于该分配的确切机制吗?你期待其他一些行为吗?尽管我们可以添加诊断打印,但您的代码中没有任何内容告诉我们正在使用什么方法。

按照python评估顺序,动作是:

In [39]: xxx = p.x
In [40]: xxx.__setitem__(0,10)

【讨论】:

  • 如果你在@x.setter 中输入print('setting x'),当你输入coordinates.x = [0, 5] 时它会被打印,但当你输入coordinates.x[0] = 3 时它不会。因此,我正在寻找一种始终打印的解决方案,即触发设置器。我问这个是因为我需要在 setter 中放一些代码
  • 诊断打印应该是原始问题的一部分。使用 @x.setter 方法无法更改 _x。正如我和其他人坚持的那样,[0]=10 步骤适用于arr.x 的结果。 python 解释器将这些作为 2 个单独的步骤执行。
  • @mauro 一旦你使用[...],就没有钩子到setter(在这种情况下甚至根本不涉及)。如果我正确理解您的意图,我看到的唯一方法是使用包含您需要的东西的__setitem__ 方法围绕np.ndarray 包装一个类,并将其直接用于_x 而不是np.ndarray(环绕因为我猜子类化将是一个主要的痛苦)。但是,这取决于你想做什么,这可能会花费你很多。
猜你喜欢
  • 1970-01-01
  • 2012-09-11
  • 2013-06-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-29
  • 1970-01-01
  • 2014-09-13
  • 1970-01-01
相关资源
最近更新 更多