【问题标题】:How to store attributes of class instance in empty dictionary in Python?如何在 Python 中将类实例的属性存储在空字典中?
【发布时间】:2019-03-07 23:21:35
【问题描述】:

我正在制作一个执行基本银行功能的自定义类。

class Account():
    '''
    A class to perform some basic banking functions
    '''
    UserList = {}   #Empty dictionary to store (UID: name) for each new instance
    def __init__(self, name, balance=0.0, uid=None):
        self.name = name    #The name of the account holder
        self.balance = balance #The initial balance
        self.uid = uid  #User ID number chosen by account holder

    @classmethod
    def new_account(cls):
        '''
        New user can specify details of account through this class method via input()
        '''
        return cls(
            input('Name: '),
            int(input('Balance: ')),
            int(input('UID: ')),
        )

    def withdraw(self, amount):
        if amount > self.balance:
            raise RuntimeError('Amount greater than available balance.')
        else:
            self.balance -= amount
            return print("After a withdrawl of {}, {}'s current balance is {}".format(amount, self.name, self.balance)) #printing balance after withdrawl

    def deposit(self, amount):
        self.balance += amount
        return print("After a deposit of {}, {}'s curent balance is {}".format(amount, self.name, self.balance)) # printing balance after deposit

基本上,新用户是通过创建Account() 类的实例来创建的,它接受名称、初始余额和用户 ID。我添加了一个类方法,以便在调用 Account.new_account() 时通过用户输入获取这些数据。我现在要做的是将每个实例(帐户)的用户 ID 和名称存储在一个空字典中。我已经玩了几个小时了,我的想法是这样的 def add_user(self, uid, name): UserList[int(self.uid)] = self.name 插入某处,但我尝试在我的代码中的几个地方实现它,它继续只返回一个空字典。有人可以帮我指出正确的方向。此外,我正在尝试实现的另外两件事是一种防止用户选择相同 UID 的方法,以及一种要求 UID 正好是 5 个数字的方法。我对 Python 比较陌生。谢谢你。

【问题讨论】:

标签: python


【解决方案1】:

您可以像之前那样将 dict 定义为类变量,但在 __init__ 方法中添加 UID 作为 dict 的键,而不是单独的 add_user 方法,这样您就可以在以下情况下始终验证 UID无论如何都会实例化一个对象:

class Account():
    users = {}
    def __init__(self, name, balance=0.0, uid=None):
        if uid in self.users:
            raise ValueError("UID '%s' already belongs to %s." % (uid, self.users[uid].name))
        if len(uid) != 5 or not uid.isdigit():
            raise ValueError("UID must be a 5-digit number.")
        self.name = name
        self.balance = balance
        self.uid = uid
        self.users[uid] = self

【讨论】:

    【解决方案2】:

    首先注意到您不能“返回打印(...”,删除打印。

    你可以这样做

    class Account():
    '''
    A class to perform some basic banking functions
    '''
    UserList = {}   #Empty dictionary to store (UID: name) for each new instance
    def __init__(self, name, balance=0.0, uid=None):
        self.name = name    #The name of the account holder
        self.balance = balance #The initial balance
        self.uid = uid  #User ID number chosen by account holder
        self.add_user(uid, name)
    
    @classmethod
    def new_account(cls):
        '''
        New user can specify details of account through this class method via input()
        '''
        return cls(
            input('Name: '),
            int(input('Balance: ')),
            int(input('UID: ')),
        )
    
    def withdraw(self, amount):
        if amount > self.balance:
            raise RuntimeError('Amount greater than available balance.')
        else:
            self.balance -= amount
            return "After a withdrawl of {}, {}'s current balance is {}".format(amount, self.name, self.balance) #printing balance after withdrawl
    
    def deposit(self, amount):
        self.balance += amount
        return "After a deposit of {}, {}'s curent balance is {}".format(amount, self.name, self.balance) # printing balance after deposit
    
    def add_user(self, uid, name):
        self.UserList[int(uid)] = name
    

    a = Account("新用户", 100, 1)

    a.add_user(2, "新用户") a.add_user(3, "新用户")

    打印(a.UserList)

    这将输出 {1: 'new user', 2: 'new user', 3: 'new user'}

    【讨论】:

    • 这是最适合我的。现在正在研究在通过类方法创建的对象上使用存款和取款方法的最佳方式。
    【解决方案3】:

    从类名中引用静态变量:

    class Account():
        user_list = {}
    
        def __init__(self, uid):
            self.uid = uid
            Account.user_list[uid] = self
    
    
    a = Account('uid')
    print(a.user_list)
    # {'uid': <__main__.Account object at 0x1043e7b38>}
    

    对于它的价值,我认为更好的方法是使用 2 个类(为方便起见,我还使用 dataclasses 自动生成一些功能 - 它不会影响核心逻辑)。那么你就完全不用担心静态变量了。

    import dataclasses
    from typing import Dict
    
    @dataclasses.dataclass
    class Account:
        uid: str
    
    
    @dataclasses.dataclass
    class Bank:
        accounts : Dict[str, Account] = dataclasses.field(default_factory=dict)
    
        def add_account(self, account):
            if account.uid in self.accounts:
                raise ValueError(f'UID : {account.uid} already exists!')
            self.accounts[account.uid] = account
    
    
    b = Bank()
    a1 = Account('a1')
    b.add_account(a1)
    print(b)
    # Bank(accounts={'a1': Account(uid='a1')})
    

    【讨论】:

    • 在你的第一个例子中,你可以只做self.user_list[uid] = self,你不需要做Account.user_list[uid] = self。只要您从不分配 self.user_list 本身(仅分配给其中的键),self.user_list 就会从类属性中无缝读取。
    • @ShadowRanger,是的,但我喜欢明确说明我的静态变量。
    猜你喜欢
    • 1970-01-01
    • 2017-11-11
    • 2021-07-28
    • 1970-01-01
    • 2016-01-05
    • 2016-07-26
    • 1970-01-01
    • 2022-01-13
    • 2012-08-23
    相关资源
    最近更新 更多