使用实例属性作为方法参数

1 投票
4 回答
610 浏览
提问于 2025-04-17 04:24

我在尝试一段代码,但我搞不清楚当我把实例属性作为参数传给一个方法时,应该怎么修改这些属性。

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

看起来当我调用 buy 方法时,系统创建了一个新的变量 stockQty。我本以为应该传递属性 qtyA 的引用,而不是它的值。这个问题可能和这个问题有关:我该如何通过引用传递变量?

我该如何解决这个问题呢?

4 个回答

0

我觉得你应该重新设计一下你的类。可以选择写几个函数,比如 buyA, buyB, buyC,并确保能重复使用一些共同的代码;或者把 buyA, buyB, buyC 合并成一个字典,然后用一个统一的函数 buy 来更新这个字典,更新时用字符串作为索引。

第一个建议只有在 A、B 和 C 在你的类中有特别的业务逻辑意义时才有意义。

0

一种简单的方法是把你想修改的成员名称作为字符串传入,比如说“qtyA”,然后用 getattr(self, stockQty) 来读取这个值,用 setattr(self, stockQty, newVal) 来改变这个值。

如果你觉得直接传字符串不太好,可以定义一些类变量,比如 refQtyA = "qtyA",然后在调用函数的时候用这些变量作为参数,比如 buy(p.refQtyA, 10, 25)

2

这个问题可能和这个问题有关:Python:我怎么通过引用传递一个变量?

确实是。

我该如何解决这个问题呢?

你需要传递一个可以被修改的值,并对其进行修改。数字是不能被直接修改的:比如说,a 可以从指向 23 变成指向 42,但你不能让 23 变成 42,或者反过来。

在你的情况下,自然的解决办法是注意到你正在做的另一个傻事——同时使用一堆相关的、名字相似的变量——并把它们替换成一个序列。list 类型是一个可以修改的序列。你需要传递整个列表,而不是仅仅一个数字,并指明要替换列表中的哪个元素。不过其实你不需要传递列表,因为它已经是 self 的一部分

class Portfolio(object):
    def __init__(self):
        self.quantity = [50, 0, 0]
        self.cash = 0  

    def __str__(self):
        return ("%d %d %d %.2f")%(self.quantity[0], self.quantity[1], self.quantity[2], self.cash)

    def buy(self, stockToBuy, amountToBuy, price, commission=20):
        self.quantity[stockToBuy] += amountToBuy
        cost = price * amountToBuy
        self.cash -= cost + commission

为了更灵活的解决方案,你可以考虑在股票名称和股票数量之间建立一种关联——毕竟,谁知道客户将来可能想要哪些股票呢。我们可以简单地使用 dict 来实现这一点。

(固定的“佣金”费用也不太现实;用百分比来计算更合理。)

撰写回答