python 如何使用 dunder 方法使 "for-iteration" 停在 "len"
python how to make "for-iteration" stop at "len" using dunder methods
我有几个 Python 类 用于调用 C 代码,使用 c-types
。 return 结构类似于下面的示例。
import ctypes
class MyCClass(ctypes.Structure):
_fields_ = [('n_values', ctypes.c_int),\
('values', ctypes.c_double * 5)]
def __repr__(self):
return """n_values : {0}, values : {1}""".format(self.n_values,\
self.values)
def __len__(self):
return self.n_values
def __getitem__(self, key):
return self.values[key]
values
数组是固定大小的,以简化对 C 的调用(此处不能使用可变大小的数组)。数组的 "actual" 长度由 n_values
变量控制。
例如,如果 values
是三个数字的数组,例如 1
、2
和 3
、values=[1, 2, 3, 0, 0]
和 n_values=3
.
这一切都很好。问题是当我实施 __len__
和 __getitem__
.
我希望能够写出这样的代码
for value in my_class:
#do something
但是迭代器似乎 "get" values
数组只有 n_values
长。 IE。它似乎没有使用 MyCClass.__len__
来停止迭代。相反,它似乎遍历了 values
.
的整个长度
my_class = MyCClass()
my_class.n_values = 3
sample_values = [1, 2, 3]
for i in range(3):
my_class.values[i] = sample_values[i]
i = 0
for value in my_class:
print(i)
i += 1
0
1
2
3
4
我要
i = 0
for value in my_class:
print(i)
i += 1
0
1
2
我知道我可以编码
for i in range(my_class):
# do something with my_class[i]
但这不是我想要的。
有人知道如何解决这个问题吗?
对于老式迭代器类型,唯一的方法是引发一个 IndexError
:
def __getitem__(self, key):
if key >= len(self):
raise IndexError
return self.values[key]
为了更简洁的解决方案,请考虑使用更现代的迭代协议,即从 iterable 上定义的 __iter__
方法返回一个 iterator 实例。记录在案 here.
我有几个 Python 类 用于调用 C 代码,使用 c-types
。 return 结构类似于下面的示例。
import ctypes
class MyCClass(ctypes.Structure):
_fields_ = [('n_values', ctypes.c_int),\
('values', ctypes.c_double * 5)]
def __repr__(self):
return """n_values : {0}, values : {1}""".format(self.n_values,\
self.values)
def __len__(self):
return self.n_values
def __getitem__(self, key):
return self.values[key]
values
数组是固定大小的,以简化对 C 的调用(此处不能使用可变大小的数组)。数组的 "actual" 长度由 n_values
变量控制。
例如,如果 values
是三个数字的数组,例如 1
、2
和 3
、values=[1, 2, 3, 0, 0]
和 n_values=3
.
这一切都很好。问题是当我实施 __len__
和 __getitem__
.
我希望能够写出这样的代码
for value in my_class:
#do something
但是迭代器似乎 "get" values
数组只有 n_values
长。 IE。它似乎没有使用 MyCClass.__len__
来停止迭代。相反,它似乎遍历了 values
.
my_class = MyCClass()
my_class.n_values = 3
sample_values = [1, 2, 3]
for i in range(3):
my_class.values[i] = sample_values[i]
i = 0
for value in my_class:
print(i)
i += 1
0
1
2
3
4
我要
i = 0
for value in my_class:
print(i)
i += 1
0
1
2
我知道我可以编码
for i in range(my_class):
# do something with my_class[i]
但这不是我想要的。
有人知道如何解决这个问题吗?
对于老式迭代器类型,唯一的方法是引发一个 IndexError
:
def __getitem__(self, key):
if key >= len(self):
raise IndexError
return self.values[key]
为了更简洁的解决方案,请考虑使用更现代的迭代协议,即从 iterable 上定义的 __iter__
方法返回一个 iterator 实例。记录在案 here.