我可以定义如何处理访问python对象(而不仅仅是它的属性)吗?
我在python中有一个自定义类,如果对象本身(即,如果其方法/属性)被访问,我希望以某种方式进行操作 这是一个精心设计的最小工作示例,用来说明我的意思。我有一个类,它保存各种我可以定义如何处理访问python对象(而不仅仅是它的属性)吗?,python,Python,我在python中有一个自定义类,如果对象本身(即,如果其方法/属性)被访问,我希望以某种方式进行操作 这是一个精心设计的最小工作示例,用来说明我的意思。我有一个类,它保存各种熊猫数据帧s,以便可以单独操作它们: 将熊猫作为pd导入 将numpy作为np导入 类SplitDataFrame: 定义初始化(self,df0,df1): self._dfs=[df0,df1] def增加(自身、数量、公司): self._dfs[num]=self._dfs[num]+inc @财产 def aso
熊猫
数据帧
s,以便可以单独操作它们:
将熊猫作为pd导入
将numpy作为np导入
类SplitDataFrame:
定义初始化(self,df0,df1):
self._dfs=[df0,df1]
def增加(自身、数量、公司):
self._dfs[num]=self._dfs[num]+inc
@财产
def asonedf(自我):
返回pd.concat(自.\u dfs,轴=1)
d=SplitDataFrame(pd.DataFrame(np.random.rand(2,2),columns=['a','b']),
数据帧(np.random.rand(2,2),列=['q','r']))
d、 增加(0,10)
这是可行的,我可以检查d.\u dfs
现在确实是
[ a b
0 10.845681 10.561956
1 10.036739 10.262282,
q r
0 0.164336 0.412171
1 0.440800 0.945003]
到目前为止,一切顺利
现在,我想更改/添加类的定义,以便在不使用.increase
方法时,返回连接的数据帧。换句话说,当访问d
时,我希望它返回与键入d.asonedf
时相同的数据帧,即
a b q r
0 10.143904 10.154455 0.776952 0.247526
1 10.039038 10.619113 0.443737 0.040389
这样,对象就更接近于pandas.DataFrame
api:
- 不需要使用
,我可以访问d.asonedf['a']
李>d['a']
- 不需要使用
,我可以使用d.asonedf+12
李>d+12
- 等等
SplitDataFrame
继承pandas.DataFrame
,但这并不能神奇地添加所需的行为
非常感谢 当然,您可以根据需要将所有相关的magic方法代理到连接的数据帧。如果你不想无休止地重复你自己,你可以动态地这样做 我并不是说这是一条路,但它是可行的:
import textwrap
import pandas as pd
import numpy as np
class SplitDataFrame:
def __init__(self, df0, df1):
self._dfs = [df0, df1]
def increase(self, num, inc):
self._dfs[num] = self._dfs[num] + inc
for name in dir(pd.DataFrame):
if name in (
"__init__",
"__new__",
"__getattribute__",
"__getattr__",
"__setattr__",
) or not callable(getattr(pd.DataFrame, name)):
continue
exec(
textwrap.dedent(
f"""
def {name}(self, *args, **kwargs):
return pd.concat(self._dfs, axis=1).{name}(*args, **kwargs)
"""
)
)
正如您可能猜到的,这个解决方案附带了各种各样的字符串,它使用了可怕的做法(使用exec
,使用dir
,…)
至少我会实现
\uuuu repr\uuuu
,这样你就不会对自己撒谎说这是什么类型的对象,也许你会想显式地枚举你想要定义的所有方法,而不是通过dir()
获取它们。您可以正常定义函数,然后在类上使用setattr
“这样,我就可以访问d['a']
”——而不是通过定义索引操作符\uu getitem\uuuuu
来实现这一点。您所要求的内容存在各种各样的概念性问题,并且不起作用。感谢@user2357112supportsMonica的评论。是的,我可以为此实现\uuuuu getitem\uuuuuuu
,我可以为+12
操作实现\uuuuuuuu
。但是我不认为包装所有的pandas.DataFrame
magic方法是一种方法;我想动态创建一个pandas.DataFrame
,其中所有功能都已经在本地实现。 你能解释一下“各种各样的概念问题”是什么意思吗?你所要求的使你无法从函数返回你的对象,或将你的对象传递给函数,或将你的对象赋给变量,或用它做几乎任何事情。它甚至会破坏您的increase
方法,因为当increase
尝试执行self.\u dfs
,并且数据帧没有\u dfs
属性时,self
将自动被数据帧替换。对你的目标做任何事情都几乎是不可能的。我很困惑这个问题与你的目标有什么本质上的区别。同样的问题问起来有点不同吗?“问一个新问题”意味着你可以问一个关于其他事情的全新问题。只是重新问几乎相同的问题并不意味着它!为什么super
?@user2357112supportsMonica是一个很好的观点,是实验遗留下来的。