假设我有一个实现__iter__()
函数的类,是首选使用iter(obj)
还是直接调用obj.__iter__()
?除了使用magic函数少输入5个字符以外,还有什么真正的区别?
相反:对于next()
和__next__()
,我可以看到魔术功能具有默认值的优点。
答案 0 :(得分:5)
区别主要是方便。它减少了打字,减少了符号的读取,因此读取速度更快。但是,各种内置函数(例如isLoggedIn = () => {
const token = this.get();
const decoded = this.decode(token);
return token && this.isNotExpired(decoded);
};
decode = (token: string) => {
const validToken = () => parts.length < 3
const parts = token ? token.split('.') : '';
if (!token || validToken()) {
return '{}';
}
const payload = validToken() ? parts[1] : '{}';
return JSON.parse(atob(payload));
};
private isNotExpired = (decodedToken) => this.getExpiryFrom(decodedToken) > new Date();
private getExpiryFrom = (decodedToken) => new Date(decodedToken.exp * 1000);
,iter
等)通常会进行一些类型检查以尽早发现错误。如果您编写了一个客户len
方法并返回了 __iter__
,则调用2
不会捕获该方法,但是obj.__iter__()
会引发类型错误。例如。
iter(obj)
>>> class X:
def __iter__(self):
return 2
>>> x = X()
>>> x.__iter__()
2
>>> iter(x)
Traceback (most recent call last):
File "<pyshell#37>", line 1, in <module>
iter(x)
TypeError: iter() returned non-iterator of type 'int'
还为没有iter
但确实实现序列协议的对象实现了迭代器协议。也就是说,它们具有__iter__
方法,该方法实现从索引0开始的序列,并为不在范围内的索引引发IndexError。这是python的较旧功能,并不是真正应该使用的新代码。例如。
__getitem__
何时应使用>>> class Y:
def __getitem__(self, index):
if 0 <= index < 5:
return index ** 2
else:
raise IndexError(index)
>>> list(iter(Y())) # iter not strictly needed here
[0, 1, 4, 9, 16]
?这可能与__iter__
不太相关,但是如果您需要访问父类使用的方法的实现,则最好以__iter__
样式调用此类方法(使用Python 3 style super用法)。例如。
super().__<dunder_method>__()