在保留对象的同时更改python迭代器
我有一个SQLAlchemy查询,它是可编辑的,假设它是一个名为在保留对象的同时更改python迭代器,python,sqlalchemy,Python,Sqlalchemy,我有一个SQLAlchemy查询,它是可编辑的,假设它是一个名为query的对象。当您对其进行迭代时,会得到如下项目: Table1('Column1', 'Column2') (each[0] for each in query) 当您在查询对象上联接表,然后对其进行迭代时,将得到元组: (Table1('Column1', 'Column2'), Table2('Column3', 'Column4')) 我知道我可以使用生成器对查询对象进行迭代,如下所示: Table1('Colum
query
的对象。当您对其进行迭代时,会得到如下项目:
Table1('Column1', 'Column2')
(each[0] for each in query)
当您在查询对象上联接表,然后对其进行迭代时,将得到元组:
(Table1('Column1', 'Column2'), Table2('Column3', 'Column4'))
我知道我可以使用生成器对查询对象进行迭代,如下所示:
Table1('Column1', 'Column2')
(each[0] for each in query)
但这并没有保留对象
query
上的任何其他方法,而是将其转换为生成器对象。有没有一种简单的方法可以在不使用其他方法的情况下更改查询的迭代部分的行为?我想出来了,我只需要使用\u getattr\u
来转发对另一个对象的访问,并用新功能定义\u iter\u
。只要我没有调用任何其他方法来扩展查询,SQLAlchemy就可以使用该方法,如果没有这些更改,查询将创建一个新对象。在我计划迭代对象之前,我通过包装对象来避免这种情况
class X:
def __init__(self):
self.prop1 = "prop1"
def __iter__(self):
yield 1
yield 2
yield 3
def method(self):
print "method 1"
class Y:
def __init__(self):
self.prop2 = "prop2"
def __iter__(self):
yield (1,2)
yield (3,4)
yield (5,6)
def another_method(self):
print "method 2"
class FirstInTuple:
def __init__(self, obj):
self.obj = obj
def __getattr__(self, attr):
return getattr(self.obj, attr)
def __iter__(self):
for each in self.obj:
if hasattr(each, '__getitem__'):
yield each[0]
else:
yield each
if __name__ == "__main__":
x = X()
y = Y()
f_x = FirstInTuple(x)
f_y = FirstInTuple(y)
for each in x:
print each
print
for each in y:
print each
print
for each in f_x:
print each
print
for each in f_y:
print each
print
print f_x.prop1
f_x.method()
print
print f_y.prop2
f_y.another_method()
输出:
1
2
3
(1, 2)
(3, 4)
(5, 6)
1
2
3
1
3
5
prop1
method 1
prop2
method 2
不是真的。查询对象被设计成有点不可变,因此您可以使用相同的“stem”查询生成两个不同的查询。