【发布时间】:2020-04-05 17:58:14
【问题描述】:
我有一个问题,我想递归地更改类中某些子元素的类。
我有一个可行的解决方案,如下所示:
class PerformanceAggregator:
def __init__(self, collection: pf.GenericPortfolioCollection):
self.collection = collection
self.change_children()
def __getattr__(self, item):
return getattr(self.collection, item, None)
def change_children(self):
for i in range(len(self.children)):
if isinstance(self.children[i], pf.GenericPortfolioCollection):
self.children[i] = PerformanceAggregator(self.children[i])
然而,change_children 方法不是很pythonic。有
会更好class PerformanceAggregator2:
def __init__(self, collection: pf.GenericPortfolioCollection):
self.collection = collection
self.change_children()
def __getattr__(self, item):
return getattr(self.collection, item, None)
def change_children(self):
for child in self.children:
if isinstance(child, pf.GenericPortfolioCollection):
child = PerformanceAggregator(child)
但是这种方法不能按预期工作。它不像第一种方法那样替换“子”元素。有人知道出了什么问题吗?
【问题讨论】:
-
在第二个示例中,
child是分配给self.children之一的变量。当您使用child = PerformanceAggregator(child)重新分配它时,您根本不会更改self.children中的引用。您只是将变量child分配给新实例,但没有其他任何事情发生,因为您从未更新父对象。 -
答案在副本中。必读:this article 详细而深入地解释了您需要了解的有关 Python“变量”的所有知识。
-
对于处理这种情况的pythonic方法:use
enumerate()这样你就可以得到孩子和它的索引。
标签: python class for-loop instance-variables