【问题标题】:Changing instance attributes in for loop in method [duplicate]在方法中更改for循环中的实例属性[重复]
【发布时间】: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


【解决方案1】:

当您循环遍历 self.children 时,您将 child 分配给 PerformanceAggregator(child),但不一定更新 self.children 中的子元素。

这应该可行:

     def change_children(self):
         for (val,child) in enumerate(self.children):
             if isinstance(child, pf.GenericPortfolioCollection):
                 self.children[val] = PerformanceAggregator(child)

【讨论】:

    猜你喜欢
    • 2021-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-23
    • 2021-08-15
    相关资源
    最近更新 更多