简体   繁体   English

在类方法中更改对象属性而不显式命名属性

[英]Change object attribute in class method without explicitly naming the attribute

I have a class Node that I built using python parent child relationship class .我有一个使用python 父子关系类构建的类 Node 。 This class defines the parent/children relationship needed to build a tree.此类定义了构建树所需的父/子关系。 In my application, I am building a balance sheet.在我的应用程序中,我正在构建资产负债表。

class Node:
_parent = None

def __init__(self, name='', attributes=None, children=None, parent=None):
    self.name = name
    self.children = children if children is not None else []
    self.parent = parent
    if children is not None:
        for child in children:
            child.parent = self

@property
def parent(self):
    return self._parent() if self._parent is not None else None

@parent.setter
def parent(self, newparent):
    oldparent = self.parent
    if newparent is oldparent:
        return
    if oldparent is not None:
        oldparent.children.remove(self)
    if self not in newparent.children:
        newparent.children.append(self)
    self._parent = weakref.ref(newparent) if newparent is not None else None

I also define a subclass LineItem that I use to populate the nodes of my tree.我还定义了一个用于填充树节点的子类 LineItem。 When a LineItem object with a given attribute (eg balance) gets added to the tree, I would like that attribute to be added and rolled up the tree.当具有给定属性(例如余额)的 LineItem 对象添加到树中时,我希望添加该属性并将树卷起。 For example, if node 1 has two children node 2 and 3 with each a balance of 10 and 20 respectively, then Node 1 would get a balance of 30.例如,如果节点 1 有两个子节点 2 和 3,每个子节点的余额分别为 10 和 20,那么节点 1 将获得 30 的余额。

class LineItem(Node):
def __init__(self, enabled=True, balance=None, native_curr=None, reported_curr='USD', *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.enabled = enabled
    self.balance = balance
    self.currency = native_curr
    self.report_curr = reported_curr
    # propagate the balance up the balance sheet
    super().addrollup(self.balance)

I created a method in the class Node that works well if the attribute is always balance.我在类 Node 中创建了一个方法,如果属性始终是平衡的,则该方法运行良好。

# propagate the quantity up
def addrollup(self, quantity):
    curr_parent = self.parent
    if quantity is not None:
        while curr_parent is not None:
            if curr_parent.balance is not None:
                curr_parent.balance += quantity
            else:
                curr_parent.balance = quantity
            curr_parent = curr_parent.parent

How would I write this function if I didn't want to explicitly call out "balance"?如果我不想明确调用“余额”,我将如何编写此函数? Is it possible to write a function generic enough that it takes an argument to define what attribute should be rolled up?是否有可能编写一个足够通用的函数,它需要一个参数来定义应该汇总的属性?

Thank you for your comment Željko Jelić.感谢您的评论 Željko Jelić。 After looking at setattr and getattr , I realized that they could be used to pass the name as an argument instead of using the self.attribute = syntax.在查看setattrgetattr 之后,我意识到它们可用于将名称作为参数传递,而不是使用 self.attribute = 语法。

I rewrote the function as我将函数重写为

    def addrollup(self, attr_name, value):
    curr_parent = self.parent
    if value is not None:
        while curr_parent is not None:
            if getattr(curr_parent, attr_name) is not None:
                setattr(curr_parent, attr_name, getattr(curr_parent, attr_name)+value)
            else:
                setattr(curr_parent, attr_name, value)
            curr_parent = curr_parent.parent

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM