python - 如何在 Python 中实现作用于实例属性的索引器/访问器
问题描述
基本目标:我有一个作为.data
属性存储在类中的数据结构。这个类也可以有自己的属性和方法。我知道这里有一个类似的设计模式,例如,pandas DataFrame 依赖于 numpy narray in .values
。我特别希望在 中包含一个 xarray 对象.data
,但它同样可以是一个 pandas DataFrame(甚至是一个列表!)用于这个讨论。我想在我的类上有一个.loc()
,或任何方法.iloc()
,.isel()
然后将该索引应用于.data
属性。它不能直接修改.data
属性(在原始实例中),因为它应该保持不变(否则您必须继续重新读取原始数据以重置您的实例.data
,这将是愚蠢的)。我认为拥有受保护._data
的财产将是大熊猫等似乎使用的技巧,但在这里看不到它的优势。看来我无论如何都必须制作(浅)副本,如:
class Mydata():
def __init__(self, attr, data):
self.attr = attr
self.data = data
def coolmethod(self):
print("Hello world")
def isel(self, index):
from copy import copy
out = copy(self)
out.data = out.data[index]
return out
isel()
所以现在我可以在我的类上调用一个方法,它在.data
不丢失数据的情况下对属性进行子集化,因此:
mydata = Mydata('a string', [0, 1, 2, 3])
mydata.data
[0, 1, 2, 3]
mydata.attr
'a string'
mydata.coolmethod()
Hello world
mydata.isel(2).data
2
mydata.isel(3).data
3
mydata.isel(3).attr
'a string'
mydata.isel(3).coolmethod()
Hello world
mydata.data
[0, 1, 2, 3]
上面的例子说明了我想要的行为。我可以在我的实例上调用一个索引器,它返回一个.data
修改后的新实例(由索引器),但其他属性仍然存在,因此允许使用不同的索引一次又一次地调用该方法。
关键似乎是制作(浅)副本。但是,这是最好的设计模式吗?我注意到,例如,pandas 确实使用属性 for.values
等.iloc
,并.iloc
返回 an_iLocIndexer
但随后我对源代码的阅读变得冷淡。这对我的用例来说太花哨了吗?定义我自己的等价物_iLocIndexer
(无论它是什么)会不会过大?.data
通过使用而不是创建从 xarray 或 pandas 等子类化的类,我是否让自己走上了一条艰难的道路?
显然,我的 real.data
会更有趣(即一个 xarray 数据集),我希望能够用它的isel
和sel
etc 索引器做同样的事情。
解决方案
推荐阅读
- python - 如何使用 gurobipy 编写最大化约束
- php - 获取产品特定数据并更新变量和单个产品
- java - 如何扩展 navHostFragment?
- docker - docker-compose env 文件在 yml 中工作,但不使用命令行参数
- javascript - 从 JavaScript 中的周数获取不正确的日期范围
- mysql - 如何搜索带有空格的术语以找到精确/相似的结果
- javascript - Javascript比较两个对象是否共享一个相同的键/值对
- javascript - 如何替换localStorage中的数据
- javascript - 反应 npm 启动命令
- c++ - 如何在 C++ 中将十六进制值转换为整数?