admin管理员组文章数量:1395012
My aim is to implement a class that inherits from pd.Series
class and acts as a container object. This object will hold varied objects as its elements in the form of
container = Container(
a = 12,
b = [12, 10, 20],
c = 'string',
name='this value',
)
I will be accessing these elements via a dot notation:
print(container.a) # Output: 12
print(container.b) # Output: [12, 10, 20]
print(container.c) # Output: string
print(container.name) # Output: None
I have tried the following implementation:
import pandas as pd
class Container(pd.Series):
def __init__(self, **kwargs):
super().__init__(data=kwargs)
This works to a large extent.
However, there would be special cases. If index
of one of the elements in the container is also a property in pd.Series()
then the property would be returned. In the case of above example, container.name
would return None
value as it returns the pd.Series().name property of the series. I want container.name to return 'this value'
.
So, maybe I need to overerite the __getattribute__
or __getattr__
to make this work.
I have tried the following:
def __getattr__(self, item):
if item in self:
return self[item]
else:
raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{item}'")
def __getattribute__(self, item):
try:
# Try to get an item using dot notation when it's available in the series itself
value = super().__getattribute__('__getitem__')(item)
if item in self:
return value
except (KeyError, AttributeError):
pass
# Fallback to the default __getattribute__
return super().__getattribute__(item)
However, this would always return RecursionError: maximum recursion depth exceeded
. I have tried different ways.
Note that I like to inherit from pd.Series()
to have access to all other functionalities of the series.
My aim is to implement a class that inherits from pd.Series
class and acts as a container object. This object will hold varied objects as its elements in the form of
container = Container(
a = 12,
b = [12, 10, 20],
c = 'string',
name='this value',
)
I will be accessing these elements via a dot notation:
print(container.a) # Output: 12
print(container.b) # Output: [12, 10, 20]
print(container.c) # Output: string
print(container.name) # Output: None
I have tried the following implementation:
import pandas as pd
class Container(pd.Series):
def __init__(self, **kwargs):
super().__init__(data=kwargs)
This works to a large extent.
However, there would be special cases. If index
of one of the elements in the container is also a property in pd.Series()
then the property would be returned. In the case of above example, container.name
would return None
value as it returns the pd.Series().name property of the series. I want container.name to return 'this value'
.
So, maybe I need to overerite the __getattribute__
or __getattr__
to make this work.
I have tried the following:
def __getattr__(self, item):
if item in self:
return self[item]
else:
raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{item}'")
def __getattribute__(self, item):
try:
# Try to get an item using dot notation when it's available in the series itself
value = super().__getattribute__('__getitem__')(item)
if item in self:
return value
except (KeyError, AttributeError):
pass
# Fallback to the default __getattribute__
return super().__getattribute__(item)
However, this would always return RecursionError: maximum recursion depth exceeded
. I have tried different ways.
Note that I like to inherit from pd.Series()
to have access to all other functionalities of the series.
1 Answer
Reset to default 1First, check if item
exists in self
using super().__contains__(item)
. If it exists, return self[item]
directly. Otherwise, fall back to the default __getattribute__
.
Here is the solution:
import pandas as pd
class Container(pd.Series):
def __init__(self, **kwargs):
object.__setattr__(self, "_custom_attrs", kwargs)
super().__init__(kwargs)
def __getattr__(self, item):
if item in self._custom_attrs:
return self._custom_attrs[item]
if item in self.index:
return super().__getitem__(item)
raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{item}'")
def __getattribute__(self, item):
if item in {"_custom_attrs", "index", "dtype", "_mgr", "_data"}:
return object.__getattribute__(self, item)
custom_attrs = object.__getattribute__(self, "_custom_attrs")
if item in custom_attrs:
return custom_attrs[item]
return pd.Series.__getattribute__(self, item)
container = Container(
a=12,
b=[12, 10, 20],
c='string',
name='this value'
)
print(container.a)
print(container.b)
print(container.c)
print(container.name)
本文标签: pythonDot notation access in pdSeries() but with priority on elements in the indexStack Overflow
版权声明:本文标题:python - Dot notation access in pd.Series() but with priority on elements in the index - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744110380a2591262.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论