I have this code I am trying out and I can’t figure out how to modify the instance attributes when I use them as parameters when calling a method.
class Portfolio(object):
def __init__(self):
self.qtyA = 50
self.qtyB = 0
self.qtyC = 0
self.cash = 0
def __str__(self):
return ("%d %d %d %.2f")%(self.qtyA, self.qtyB, self.qtyC, self.cash)
def buy(self, stockQty, qtyToBuy, price, commission=20):
stockQty += qtyToBuy
print stockQty
buyTransaction = price * qtyToBuy
self.cash -= buyTransaction + commission
>>> p = Portfolio()
>>> p.buy(p.qtyA,10,25)
60
>>> print p
50 0 0 -270.00
What seems to be happening is that a new variable stockQty is being created when buy is called. I would expect that a reference to the attribute qtyA would be passed instead of the value. This problem might be related to this question: How do I pass a variable by reference?
How can I work around this issue?
It is.
You need to pass a value that can be modified, and modify it. Numbers cannot be modified:
acan be changed from referring to23to referring to42instead, but you cannot cause23to become42or vice-versa.In your case, the natural way to do this is to also notice the other silly thing you’re doing – using a bunch of related, similarly-named variables in parallel – and fix that as well, by replacing them with a sequence. The
listtype is a modifiable sequence. You need to pass the list itself instead of just a numeric quantity, and indicate which element of the list to replace. Except you don’t actually need to pass the list, because it’s already a part ofself.For a more flexible solution, you might consider the idea of having an association between stock names and quantities of stock – after all, who knows what stocks the client might want in the future. We can do this simply by using a
dictinstead.(A constant ‘commission’ cost is also unrealistic; a percentage makes more sense.)