如何从另一个实例中更改类的实例

问题描述 投票:0回答:2

我正在研究 python 并遇到了我试图解决的这个问题。它可能有一个简单的解决方案,我仍然没有学习或找不到。 我有一个名为 Category 的类,它有一个方法来进行存款、取款和转账,该方法将此操作写入一个名为 ledger 的列表。 我将 Category 类实例化为食物,进行存款和两次取款,效果很好。然后我创建了一个名为 clothing 的 Category 类的新实例,但是当我尝试从食品分类账转移到服装分类账时,我做不到。它从食品分类账中提取,这部分有效,但是当我尝试向服装分类账存入款项时,存款却存入了同一个食品分类账。 我究竟做错了什么?谁能帮帮我?

class Category:
    ledger = list()
    category_name = ''
    def __init__(self, category):
        self.category_name = category

    def deposit(self, amount, description=''):
        entry = dict()
        entry['amount'] = amount
        entry['description'] = description
        self.ledger.append(entry)

    def withdraw(self, amount, description=''):
        if self.check_funds(amount):
            entry = dict()
            entry['amount'] = -abs(amount)
            entry['description'] = description
            self.ledger.append(entry)
            return True
        else:
            return False

    def transfer(self, amount, to_category):
        if self.check_funds(amount):
            self.withdraw(amount, "Transfer to " + to_category.category_name)
            to_category.deposit(amount, 'Transfer from ' + self.category_name)
            return True
        else:
            return False

    def get_balance(self):
        balance = 0
        for entry in self.ledger:
            balance = balance + entry.get('amount')
        return balance

    def check_funds(self, amount):
        if self.get_balance() >= amount:
            return True
        else:
            return False
        


def create_spend_chart(categories):
    categories = categories


food = Category("Food")
food.deposit(1000, "initial deposit")
food.withdraw(10.15, "groceries")
food.withdraw(15.89, "restaurant and more food for dessert")
clothing = Category("Clothing")
food.transfer(50, clothing)
# clothing.withdraw(25.55)
# clothing.withdraw(100)
python class instance
2个回答
0
投票

您面临的问题是由于您在 Category 类中定义 ledger 属性的方式。通过将其定义为类属性而不是实例属性,Category 类的所有实例共享同一个列表对象。这意味着当您从食品类别转移到服装类别时, to_category.deposit(amount, 'Transfer from ' + self.category_name) 行将存款添加到 Category.ledger 列表而不是 clothing.ledger列表。

要解决此问题,您可以通过在 init 方法中初始化它来将 ledger 属性定义为实例属性:

class Category:
    category_name = ''
    def __init__(self, category):
        self.category_name = category
        self.ledger = []
        # rest of the code...

这将为类别类的每个实例创建一个新的分类帐列表,这将防止您面临的问题。


-1
投票

只有一个

ledger
。您为
Category
类定义了它,并且它属于谁,无论您将它子类化多少次。

您可以通过在每个子类上分别定义

ledger
来避免这种情况。但是,这有可能导致大量重复,并且会导致将来难以添加更多子类。与其将
ledger = list()
写入每个子类,不如在
ledger
:
__init_subclass__
 方法中自动添加 
Category

def __init_subclass__(cls):
    cls.ledger = list()
© www.soinside.com 2019 - 2024. All rights reserved.