在构建一个如下所示的out行的类时,我想要for循环的行为,如果完成一次:只需按正常方式键,然后转到下一行代码。但是如果在第一个循环中设置了第二个循环,它将在第一个循环中给出键,然后在第二个循环中的序列中给出ea值。我无法弄清楚的问题是如何在 iter 下设置它。
class MyClass():
def __init__(self):
self.cont1 = [1,2,3,4]
self.cont2 = ('a','b','c')
def __iter__(self):
pass # ???????
这样的事情:
dct = dict(container1=[5,6,7,8], container2=('a','b','c')
if one loop is used:
for ea in dct:
print(ea)
print("Howdy")
'containter1'
'containter2'
Howdy
如果使用嵌套循环:
for ea in dct:
print(ea)
for i in dct.get(ea):
print(i)
'container1'
5
6
...
'container2'
a
b
c
答案 0 :(得分:1)
要回答您的直接问题,您可以复制字典的实施方式dict.get
和dict.__iter__
:
class MyClass():
def __init__(self):
self.cont1 = [1,2,3,4]
self.cont2 = ('a','b','c')
def __iter__(self):
for attr in dir(self):
if not attr.startswith('_') and attr != 'get':
yield attr
def get(self, key):
return getattr(self, key)
然而,这不是一个非常好的方法。在运行时查看对象的属性不是一个好主意,因为它会在您子类化时中断,并且会增加不必要的复杂性。相反,只需在内部使用字典:
class MyClass():
def __init__(self):
self.container = {
'cont1': [1, 2, 3, 4],
'cont2': ('a', 'b', 'c')
}
def __iter__(self):
return iter(self.container)
def get(self, key):
return self.container.get(key)
答案 1 :(得分:0)
你对此感觉如何:
class MyClass():
def __init__(self):
self.cont1 = [1,2,3,4]
self.cont2 = ('a','b','c')
self.conts = {'container1':self.cont1, 'container2':self.cont2}
def __iter__(self):
return self.conts.iteritems()
dct = MyClass()
print('One loop')
for mi in dct:
print(mi)
print('='*40)
print('Nested loops')
for name, values in dct:
print(name)
for i in values:
print(i)
哪个输出:
One loop
container1
container2
========================================
Nested loops
container1
1
2
3
4
container2
a
b
c
我不知道我真的会推荐这个,但这似乎更符合OP的要求:
class MyIterator(object):
def __init__(self, name, values):
self.vals = iter(values)
self.name = name
def __iter__(self):
return self.vals
def __str__(self):
return self.name
class MyClass():
def __init__(self):
self.cont1 = [1,2,3,4]
self.cont2 = ('a','b','c')
self.conts = [MyIterator('container1', self.cont1),
MyIterator('container2', self.cont2)]
def __iter__(self):
return iter(self.conts)
dct = MyClass()
for mi in dct:
print(mi)
for i in mi:
print(i)
这是我能想到的能够打印名称然后作为值列表迭代它的唯一方法。这可以通过覆盖__str__
方法来改变对象的获取方式"字符串化"。但正如我之前所说,我认为答案的第一部分会更好。
抱歉,刚刚意识到nauer's answer已经显示过这样的内容。
答案 2 :(得分:0)
您可以使用第二个类
来完成此操作class MyClass():
def __init__(self):
self.data = [MyClass2({'cont1' : [1,2,3,4]}),MyClass2({'cont2' : ('a','b','c')})]
def __iter__(self):
for item in self.data:
yield item
class MyClass2():
def __init__(self, mydict):
self.d = mydict
def __iter__(self):
for item in self.d.values():
for value in item:
yield value
def __repr__(self):
return(list(self.d.keys())[0])
m = MyClass()
for k in m:
print(k)
for val in k:
print(val)
答案 3 :(得分:0)
仅通过实施__iter__
,您无法做到这一点。 __iter__
应该返回一个迭代器,即一个保持迭代状态的对象(项目序列中的当前位置),并且有一个方法next
返回每次调用时序列中的下一个项目。
如果您的对象具有嵌套序列,则可以实现仅遍历外部序列的迭代器,或者遍历两者的迭代器 外部序列和内部序列 - 以深度优先或呼吸优先的方式 - 但在同一个迭代中使用嵌套循环没有意义:
# iterate over every item in myobj
for x in myobj:
...
# iterate over every item again? not likely what you want!
for y in myobj:
更可能的情况是:
for x in myob:
...
for y in x:
...