Python 重载__setitem__不会替换类范围之外的 self

Python overload __setitem__ does not replace self out of the class range

提问人:KYPcode 提问时间:8/14/2023 更新时间:8/14/2023 访问量:43

问:

我正在尝试创建一种继承极坐标的数据帧子类。数据帧。我想修改方法以使以下陈述成为可能:__setitem__

df['test_column'] = 'test'

但是,当我重载 时,似乎如果该方法没有修改类之外的项目。__setitem__

这是一个简单的案例,只是为了看看我如何做到这一点。所以,我这样做了:

class CustomDataFrame(pl.DataFrame):
    def __setitem__(self, key, value):
        if isinstance(key, str) and isinstance(value, str):
            self = self.with_columns(pl.lit(value).alias(key))
            print(self)
        else:
            super().__setitem__(key, value)

然后我用它来测试我的代码:

data = {'test_column': [1, 2, 3, 4, 5], 'test_column1':[1,3,3,4,5]}
df = CustomDataFrame(data)
df['test_column'] = 'test'
print(df)

问题是不打印修改后的数据帧,而是打印“初始”数据帧。因此,在方法内部打印修改后的数据帧。print(df)print(self)__setitem__

这就像如果修改的范围没有超过类的内部。有人知道为什么我的代码不起作用吗?self

python 重载 magic-methods python-class

评论

0赞 juanpa.arrivillaga 8/14/2023
可能是因为只是创建一个新的数据框并将其分配给局部变量。为变量赋值不会改变对象。考虑一下,如果你有,它只是,然后会打印self = self.with_columns(...)selfdef foo(x):x = 0x = 1; foo(x); print(x)1

答:

0赞 Nopileos 8/14/2023 #1

你不能在函数中覆盖 self,这只会将你拥有的任何内容绑定到一个名为 self 的局部变量,这将在函数完成后被删除。您不能以任何方式更改您的对象。

如果你想覆盖它,你可以尝试这个答案中提出的一些建议。

按照答案,我想出了这个代码。我没有更改,因为这应该仍然是您的 CustomDataFrame,而不是突然的极地。至少从印刷品来看,分配似乎有效。__class____dict__

imo仍然非常危险。只要你的类保持这样简单,它可能没问题,一旦你的类也向 self 添加变量,这就会中断。不知道这样做是否还会有副作用。

你可能应该考虑一下你是否真的需要这个,如果你真的需要这种方式,而不是例如创建一个函数,当你需要这个特殊情况时,你试图在你当前覆盖。__setitems__

import polars as pl


class CustomDataFrame(pl.DataFrame):
    def __setitem__(self, key, value):
        if isinstance(key, str) and isinstance(value, str):
            tmp = self.with_columns(pl.lit(value).alias(key))
            self.__dict__ = tmp.__dict__
            print(self)
        else:
            super().__setitem__(key, value)


data = {'test_column': [1, 2, 3, 4, 5], 'test_column1':[1,3,3,4,5]}
df = CustomDataFrame(data)
df['test_column'] = 'test'
print(df.__class__, df)

评论

0赞 KYPcode 8/14/2023
很清楚!非常感谢:)