像dict[]一样从Class中提取元素值——__getitem__

背景

最近在看代码时,发现python中的类可以像dict一样直接取元素,这是我之前没有碰到过的。便上午查阅资料,发现原来是python类中的__getitem__方法在作怪,寻找解决方案,并记录一下。

理解 getitem 方法

原理

通过key或index获取item的语法[]只是语法小技巧。当你执行 a[i]时Python调用的方法其实是a.__getitem__(i)

一个小举例

把类(Class)想象成是一个建筑模型。在建筑的数据中包含许多属性,包括对占据每层楼公司的描述:

class Building(object):
     def __init__(self, floors):
         self._floors = [None]*floors
     def occupy(self, floor_number, data):
          self._floors[floor_number] = data
     def get_floor_data(self, floor_number):
          return self._floors[floor_number]

building1 = Building(4) # Construct a building with 4 floors
building1.occupy(0, 'Reception')
building1.occupy(1, 'ABC Corp')
building1.occupy(2, 'DEF Inc')
print( building1.get_floor_data(2) )

Output:

DEF Inc

然而,我们可以使用 __getitem__(及其对应的 __setitem__)方法来使 Building 类的使用“更好”。

class Building(object):
     def __init__(self, floors):
         self._floors = [None]*floors
     def __setitem__(self, floor_number, data):
          self._floors[floor_number] = data
     def __getitem__(self, floor_number):
          return self._floors[floor_number]

building1 = Building(4) # Construct a building with 4 floors
building1[0] = 'Reception'
building1[1] = 'ABC Corp'
building1[2] = 'DEF Inc'
print( building1[2] )

Output:

DEF Inc

当然,是否需要像这样使用 __setitem__, __getitem__取决于具体如何提取数据。 - 在上述举例中,我们将建筑物视为楼层的容器。(也可以为建筑物实现迭代器,甚至可以实现 切片 , 即一次获取多个楼层的数据 等)

参考

Understanding getitem method
A python class that acts like dict

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
`__class_getitem__`是Python 3.7引入的一个特殊方法,用于动态创建泛型类型。它是一个类方法,用于获取一个类的泛型参数,并返回一个新的泛型类型。 `types.GenericAlias`是Python 3.7引入的一个内置类型,用于创建泛型类型。它接受两个参数:`origin`和`args`。其,`origin`表示泛型类型的原始类型,例如`List`、`Tuple`、`Dict`等;`args`表示泛型类型的参数,例如`List[int]`、`Tuple[str, int]`、`Dict[str, float]`等。 当我们使用`__class_getitem__`方法来创建泛型类型时,我们需要将其设置为`classmethod`,并将其定义为`types.GenericAlias`。这样,当我们创建一个泛型类型时,Python会自动调用`__class_getitem__`方法来解析泛型参数,并返回一个新的泛型类型。 下面是一个使用`__class_getitem__`和`types.GenericAlias`创建泛型类型的示例代码: ```python import types class MyList(list): @classmethod def __class_getitem__(cls, params): return types.GenericAlias(list, params) # 创建一个泛型类型 MyListInt = MyList[int] # 创建一个实例 my_list = MyListInt([1, 2, 3, 4, 5]) # 输出实例的类型和 print(type(my_list)) print(my_list) ``` 在这个示例,我们定义了一个`MyList`类,它继承自Python内置的`list`类,并重载了`__class_getitem__`方法。在`__class_getitem__`方法,我们使用`types.GenericAlias`创建一个新的泛型类型,并将其返回。然后,我们使用`MyListInt = MyList[int]`创建一个`int`类型的泛型`MyList`类型,并使用`MyListInt([1, 2, 3, 4, 5])`创建一个实例。最后,我们输出实例的类型和,可以看到它是一个`MyListInt`类型的实例,且其为`[1, 2, 3, 4, 5]`。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiu_cs

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值