开发者

Python: recursive way to subtract from class attributes?

I have a class with many attributes, and when I give a number, I would like it to开发者_StackOverflow subtract that from one attribute, but if the amount is greater than the attribute subtracted from, move to the next attribute with what is left over. Example:

def subt(self, amount):
    self.attr1 += amount
    if self.attr1 < 0:
        self.attr2 += self.attr1
        self.attr1 = 0
        if self.attr2 < 0:
            # etc...

It feel like there should be a concise recursive way to accomplish the same thing, but I don't know how with the all the different attributes.


You can access the attributes using .__dict__ You need a list for the order you want to subtract. Something like this works.

class A():
    def __init__(self):
        self.foo = 100
        self.bar = 200
        self.baz = 300
        self.sub_stack = ['foo', 'baz', 'bar']

    def subt(self, amount):
        tmp_stack = self.sub_stack[:]
        while tmp_stack and amount:
            key = tmp_stack.pop(0)
            val = self.__dict__[key]
            if val > amount:
                self.__dict__[key] -= amount
                amount = 0
            else:
                amount -= self.__dict__[key]
                self.__dict__[key]=0
        return amount 

return value is the remainder on amount after iterating through your attributes


Does making a list out of all the attributes work?

def subt(self, amount): 
    i = 0
    while i<self.attrlist.len:
        if attrlist[i] < amount:
            attrlist[i] -= amount
            break


Yes, the best way is to create a list of all your attributes - do it either manually, or, if your attribute names follow a pattern (like the attrN series on the example), you can automate the creation of such a list.

def subt(self, amount):
    #all_attrs = ["attr1", "attr2", "attr3"]
    # or this step can be automated by something like:
    all_attrs = sorted(attr_name for attr_name in self.__class__.__dict__.keys() if attr_name.startswith("attr"))
    for i, attr_name in all_attrs:
        self.__setattr__(getattr(self, attr_name) + amount)
        if gettattr(self, attr_name) < 0:
            amount = gettattr(self, attr_name)
            self.__setattr__(self, attr_name, 0)
        else: 
            break
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜