迭代类对象 [英] Iterating class object

查看:50
本文介绍了迭代类对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这不是一个现实世界的程序,但我想知道为什么它不能完成.

我在考虑 numpy.r_ 对象并尝试做类似的事情,但只是创建一个类并且不实例化它.

一个简单的整数代码(有一些缺陷)可能是:

class r_:@类方法def __getitem__(clc, sl):尝试:返回范围(sl)除了类型错误:sl = sl.start, sl.stop, sl.step返回范围(*(i for i in sl if i is not None))

但是当我尝试执行 r_[1:10] 时,我收到 TypeError: 'type' object is not subscriptable.

当然,代码适用于 r_.__getitem__(slice(1,10)) 但这不是我想要的.

在这种情况下,我可以做些什么而不是使用 r_()[1:10] 吗?

解决方案

解析obj[index]的协议是在中寻找__getitem__方法obj 的 >type 直接在 obj 上查找方法(通常会回退到查找方法如果 obj 没有名称为 __getitem__ 的实例属性,则在类型上).

这很容易验证.

<预><代码>>>>类 Foo(对象):经过>>>def __getitem__(self, index):回报指数>>>f = Foo()>>>f.__getitem__ = __getitem__>>>[3]回溯(最近一次调用最后一次):文件<pyshell#8>",第 1 行,在 <module> 中[3]类型错误:'Foo' 对象不支持索引>>>Foo.__getitem__ = __getitem__>>>[3]3

我不知道为什么它会以这种方式工作,但我想至少部分原因正是为了阻止您尝试做的事情;如果每个定义 __getitem__ 以便其实例可索引的类意外地获得了对自身进行索引的能力,那将是令人惊讶的.在绝大多数情况下,试图索引一个类的代码将是一个错误,所以如果 __getitem__ 方法碰巧能够返回一些东西,如果它没有被捕获就会很糟糕.

为什么不直接调用该类,并将它的一个实例绑定到名称 r_ 上?然后你就可以做r_[1:10].

It's not a real world program but I would like to know why it can't be done.

I was thinking about numpy.r_ object and tried to do something similar but just making a class and not instantiating it.

a simple code (has some flaws) for integers could be:

class r_:
    @classmethod
    def __getitem__(clc, sl):
        try:
            return range(sl)
        except TypeError:
            sl = sl.start, sl.stop, sl.step
            return range(*(i for i in sl if i is not None))

but as I try to do r_[1:10] i receive TypeError: 'type' object is not subscriptable.

Of course the code works with r_.__getitem__(slice(1,10)) but that's not what I want.

Is there something I can do in this case instead of using r_()[1:10]?

解决方案

The protocol for resolving obj[index] is to look for a __getitem__ method in the type of obj, not to directly look up a method on obj (which would normally fall back to looking up a method on the type if obj didn't have an instance attribute with the name __getitem__).

This can be easily verified.

>>> class Foo(object):
    pass

>>> def __getitem__(self, index):
    return index

>>> f = Foo()
>>> f.__getitem__ = __getitem__
>>> f[3]
Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    f[3]
TypeError: 'Foo' object does not support indexing
>>> Foo.__getitem__ = __getitem__
>>> f[3]
3

I don't know why exactly it works this way, but I would guess that at least part of the reason is exactly to prevent what you're trying to do; it would be surprising if every class that defined __getitem__ so that its instances were indexable accidentally gained the ability to be indexed itself. In the overwhelming majority of cases, code that tries to index a class will be a bug, so if the __getitem__ method happened to be able to return something, it would be bad if that didn't get caught.

Why don't you just call the class something else, and bind an instance of it to the name r_? Then you'd be able to do r_[1:10].

这篇关于迭代类对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆