dataset__getitem___【Pytorch】Pytorch中Dataset类是否为Iterator的探讨

今天在研究pytorch的Dataset的时候,查看了下源码,如下:

class Dataset(object):
    """An abstract class representing a Dataset.

    All other datasets should subclass it. All subclasses should override
    ``__len__``, that provides the size of the dataset, and ``__getitem__``,
    supporting integer indexing in range from 0 to len(self) exclusive.
    """

    def __getitem__(self, index):
        raise NotImplementedError

    def __len__(self):
        raise NotImplementedError

    def __add__(self, other):
        return ConcatDataset([self, other])

突然有一个疑问,pytorch中说Dataset是一个迭代器,但是迭代器不是要实现__iter____next__方法吗?为啥Dataset没有呢?并且,如下操作并是正确的。

train_loader = BaseDatalayer(cfg)  # BaseDatalayer继承于Dataset
for data in train_loader:
    print(data)

进一步探究发现,发现 __iter__ 和 __getitem__ 中实现任意一个,对象就是可迭代的,怎么解释这种情况呢,Python 解释器中有这样的描述:

解释器需要迭代对象 x 时, 会自动调用 iter(x)。 内置的 iter 函数有以下作用:

(1) 检查对象是否实现了 __iter__ 方法, 如果实现了就调用它, 获取 一个迭代器;

(2) 如果没有实现 __iter__ 方法, 但是实现了 __getitem__ 方法, Python 会创建一个迭代器, 尝试按顺序(从索引 0 开始) 获取元素;

(3) 如果尝试失败, Python 抛出 TypeError 异常, 通常会提示“C object is not iterable”(C 对象不可迭代), 其中 C 是目标对象所属的类。任何 Python 序列都可迭代的原因是, 它们都实现了 __getitem__ 函数。 其实, 标准的序列都实现了 __iter__ 函数, 因此你也应该这么做。

总结

因此我们在自定义可迭代对象需要实现 __iter__ 函数;严格来讲,我们还需要实现 __getitem__ 函数,这个函数的主要作用是当前对象可通过下标取值。

另外,如果有一个未知的对象,我们怎么判断该对象是否可迭代呢,两种方式。

(1):iter(x) :这是最准确的判断方式,传入要判断的对象,只要对象实现了__getitem__ 、 __iter__中的其中一个,该对象都是可迭代的,否则抛出TypeError: 'C' object is not iterable 异常;这儿有个区别,如果仅仅实现了 __getitem__ ,调用 iter(x) 返回的是迭代器对象,如果实现的是 __iter__ ,那么调用 iter(x) 返回的是生成器对象;

(2): isinstance(x, abc.Iterable) :该方式会自动忽略 __getitem__ 函数,仅当对象实现了 __iter__ 函数才返回 True,其他一律返回 False。

文章参考:

Python中自定义可迭代对象​www.jianshu.com
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值