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
精彩评论