python - 为什么为 __getitem__ 分配一个类不起作用?
问题描述
这是一个list
子类,它将其项目委托给itertools.compress
.
from itertools import compress
class WeirdList(list):
def __getitem__(self, item):
return compress(self, item)
l = WeirdList([1, 2, 3, 4])
print(*l[0, 1, 0, 1]) # 2 4
以上工作正常,虽然我的印象是我可以直接分配compress
给__getitem__
.
class WeirdList(list):
__getitem__ = compress
l = WeirdList([1, 2, 3, 4])
print(*l[0, 1, 0, 1])
这引发了以下问题:
Traceback (most recent call last):
File "...", line 7, in <module> print(*l[0, 1, 0, 1])
TypeError: Required argument 'selectors' (pos 2) not found
我相信这会中断,因为compress
它是一个类而不是一个函数,但消息显示TypeError
是从调用中引发的compress
。
什么时候__getitem__
协议调用compress
了一个参数?
解决方案
函数可以用作方法,因为它具有__get__
属性。该类没有属性 :compress
__get__
>>> compress.__get__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'itertools.compress' has no attribute '__get__'
所以不能是一种方法。
使用__get__
方法调用属性时,__get__
会调用该方法并返回其返回值,而不是属性本身的值。也就是说,l[0] == l.__getitem__(0) == l.__getitem__.__get__(l, type(l))(0)
的返回值__get__
是一个已经l
传递给函数的对象。
(如果您想知道装饰器classmethod
和staticmethod
装饰器的作用,它们会使用不同的__get__
方法返回对象。)
推荐阅读
- java - 将java枚举映射到整数
- python - 隔离森林的 ROC 曲线
- ruby-on-rails - 如何在开发过程中关闭 Rails 缓存
- c - 为什么正则表达式总是真或总是假
- php - 向 Laravel 项目添加多个中间件
- git - “git clone user@server/my-repo.git”和“git clone git://user@server/my-repo.git”有什么区别
- python - 将元素添加到指定数据框行中的列表
- javascript - Javascript 代理和传播语法,结合 console.log
- sql-server - 递归 CTE 层次结构中的双行
- arrays - 压缩最近邻算法 - 返回数组的混淆