python - python - 为什么在python OOP中将相同的对象附加到不同的列表时会得到不同的对象ID?
问题描述
我的 OOP 银行应用程序中有存款、取款和转账方法,这些方法似乎正在打印正确的值,但如果我删除repr方法,它会显示 1 ID 不相同。
编辑:我的其他课程,不确定是否相关:
class PersonError(Exception):
"""Person error."""
pass
class TransactionError(Exception):
"""Transaction error."""
pass
class Person:
"""Person class."""
def __init__(self, first_name: str, last_name: str, age: int):
"""
Person constructor.
:param first_name: first name
:param last_name: last name
:param age: age, must be greater than 0
"""
if not first_name or not last_name:
raise PersonError
else:
self.first_name = first_name
self.last_name = last_name
self.bank_account = None
if age <= 0:
raise PersonError
else:
self._age = age
@property
def full_name(self) -> str:
"""Get person's full name. Combination of first and last name."""
return f"{self.first_name} {self.last_name}"
@property
def age(self) -> int:
"""Get person's age."""
return self._age
@age.setter
def age(self, value: int):
"""Set person's age. Must be greater than 0."""
if value <= 0:
raise PersonError
else:
self._age = value
def __repr__(self) -> str:
"""
Person representation.
:return: person's full name
"""
return self.full_name
class Bank:
"""Bank class."""
def __init__(self, name: str):
"""
Bank constructor.
:param name: name of the bank
"""
self.name = name
self.customers = []
self.transactions = []
def add_customer(self, person: Person) -> bool:
"""
Add customer to bank.
:param person: person object
:return: was customer successfully added
"""
if person not in self.customers:
self.customers.append(person)
person.bank_account = Account(0, person, bank)
return True
else:
return False
def remove_customer(self, person: Person) -> bool:
"""
Remove customer from bank.
:param person: person object
:return: was customer successfully removed
"""
if person in self.customers:
self.customers.remove(person)
person.bank_account = None
return True
else:
return False
def __repr__(self) -> str:
"""
Bank representation.
:return: name of the bank
"""
return self.name
class Transaction:
"""Transaction class."""
def __init__(self, amount: float, date: datetime.date, sender_account: 'Account', receiver_account: 'Account',
is_from_atm: bool):
"""
Transaction constructor.
:param amount: value
:param date: date of the transaction
:param sender_account: sender's object
:param receiver_account: receiver's object
:param is_from_atm: is transaction from atm
"""
self.is_from_atm = is_from_atm
self.receiver_account = receiver_account
self.sender_account = sender_account
self.date = date
self.amount = amount
def __repr__(self) -> str:
"""
Transaction representation.
:rtype: object's values displayed in a nice format
"""
if self.is_from_atm is True:
return f"({self.amount} €) ATM"
elif self.is_from_atm is False:
return f"({self.amount} €) {self.sender_account.person} -> {self.receiver_account.person}"
我的方法:
class Account:
"""Account class."""
def __init__(self, balance: float, person: Person, bank: 'Bank'):
"""
Account constructor.
:param balance: initial account balance
:param person: person object
:param bank: bank object
"""
self.bank = bank
self.person = person
self._balance = balance
self.number = f"EE{randint(111111111111111111, 999999999999999999)}"
self.transactions = []
@property
def balance(self) -> float:
"""Get account's balance."""
return self._balance
def deposit(self, amount: float, is_from_atm: bool = True):
"""Deposit money to account."""
if amount <= 0:
raise TransactionError
elif is_from_atm is True:
t = Transaction(amount, date=datetime.date.today(), sender_account=self, receiver_account=self, is_from_atm=True)
self._balance = self._balance + amount
self.transactions.append(t)
bank.transactions.append(t)
elif is_from_atm is False:
self._balance = self._balance + amount
def withdraw(self, amount: float, is_from_atm: bool = True):
"""Withdraw money from account."""
if amount <= 0 or amount > self._balance:
raise TransactionError
elif is_from_atm is True:
t = Transaction(-amount, date=datetime.date.today(), sender_account=self, receiver_account=self, is_from_atm=True)
self._balance = self._balance - amount
self.transactions.append(t)
bank.transactions.append(t)
elif is_from_atm is False:
self._balance = self._balance - amount
def transfer(self, amount: float, receiver_account: 'Account'):
"""Transfer money from one account to another."""
fee = 5
if receiver_account == self:
raise TransactionError
elif (self._balance - fee - amount) < 0:
raise TransactionError
elif receiver_account.bank != self.bank and amount >= 0:
t = Transaction(amount, datetime.date.today(), sender_account=self, receiver_account=receiver_account,
is_from_atm=False)
self._balance = self._balance - amount - fee
self.transactions.append(t)
self.bank.transactions.append(t)
t = Transaction(amount, datetime.date.today(), sender_account=self, receiver_account=receiver_account,
is_from_atm=False)
receiver_account._balance = receiver_account._balance + amount
receiver_account.transactions.append(t)
receiver_account.bank.transactions.append(t)
elif receiver_account.bank == self.bank and amount >= 0:
t = Transaction(amount, datetime.date.today(), sender_account=self, receiver_account=receiver_account,
is_from_atm=False)
self._balance = self._balance - amount
self.transactions.append(t)
self.bank.transactions.append(t)
t = Transaction(amount, datetime.date.today(), sender_account=self, receiver_account=receiver_account,
is_from_atm=False)
receiver_account._balance = receiver_account._balance + amount
receiver_account.transactions.append(t)
如果名称是主要的:
if __name__ == '__main__':
person = Person("Ago", "Luberg", 100)
bank = Bank("TalBank")
bank.add_customer(person)
a1 = person.bank_account
person2 = Person("Mati", "Maal", 90)
bank.add_customer(person2)
a2 = person2.bank_account
a1.deposit(100)
a2.deposit(100)
a1.withdraw(10)
a2.withdraw(50)
a1.transfer(10, a2)
print(a1.transactions) # [(100 €) ATM, (-10 €) ATM, (10 €) Ago Luberg -> Mati Maal]
print(a2.transactions) # [(100 €) ATM, (-50 €) ATM, (10 €) Ago Luberg -> Mati Maal]
print(bank.transactions)
# [(100 €) ATM, (100 €) ATM, (-10 €) ATM, (-50 €) ATM, (10 €) Ago Luberg -> Mati Maal]
打印交易时我的输出没有repr :
1. person1 transactions [<__main__.Transaction object at 0x0000024AE1ACF4F0>, <__main__.Transaction object at 0x0000024AE1ACF490>, <__main__.Transaction object at 0x0000024AE1ACF340>]
2. person2 transactions [<__main__.Transaction object at 0x0000024AE1ACF520>, <__main__.Transaction object at 0x0000024AE1ACF400>, <__main__.Transaction object at 0x0000024AE1ACF2B0>]
3. bank transactions(person1 + person2 transactions) [<__main__.Transaction object at 0x0000024AE1ACF4F0>, <__main__.Transaction object at 0x0000024AE1ACF520>, <__main__.Transaction object at 0x0000024AE1ACF490>, <__main__.Transaction object at 0x0000024AE1ACF400>, <__main__.Transaction object at 0x0000024AE1ACF340>]
没有repr方法的预期输出:
1. person1 transactions [<__main__.Transaction object at 0x0000024AE1ACF4F0>, <__main__.Transaction object at 0x0000024AE1ACF490>, <__main__.Transaction object at 0x0000024AE1ACF340>]
2. person2 transactions [<__main__.Transaction object at 0x0000024AE1ACF520>, <__main__.Transaction object at 0x0000024AE1ACF400>, <__main__.Transaction object at 0x0000024AE1ACF340>]
3. bank transactions(person1 + person2 transactions) [<__main__.Transaction object at 0x0000024AE1ACF4F0>, <__main__.Transaction object at 0x0000024AE1ACF520>, <__main__.Transaction object at 0x0000024AE1ACF490>, <__main__.Transaction object at 0x0000024AE1ACF400>, <__main__.Transaction object at 0x0000024AE1ACF340>]
我的问题是为什么 person2 交易中的最后一个交易对象与 person1 和银行交易中的最后一个交易对象不同,尽管使用repr方法它们是相同的。
使用repr方法输出:
[(100 €) ATM, (-10 €) ATM, (10 €) Ago Luberg -> Mati Maal]
[(100 €) ATM, (-50 €) ATM, (10 €) Ago Luberg -> Mati Maal]
[(100 €) ATM, (100 €) ATM, (-10 €) ATM, (-50 €) ATM, (10 €) Ago Luberg -> Mati Maal]
预先感谢任何希望在他们的帮助下做出贡献的人!赤红。
解决方案
在这部分代码中:
elif receiver_account.bank != self.bank and amount >= 0:
t = Transaction(amount, datetime.date.today(), sender_account=self, receiver_account=receiver_account,
is_from_atm=False)
self._balance = self._balance - amount - fee
self.transactions.append(t)
self.bank.transactions.append(t)
t = Transaction(amount, datetime.date.today(), sender_account=self, receiver_account=receiver_account,
is_from_atm=False)
receiver_account._balance = receiver_account._balance + amount
receiver_account.transactions.append(t)
receiver_account.bank.transactions.append(t)
您要声明t
两次:声明一次,然后将其附加到self.transactions
,然后再声明一次(因此它等于另一个对象引用)并将其附加到receiver_account
. 所以t
第一次和第二次不是同一个对象。
删除第二个声明t
应该会给您预期的结果。
推荐阅读
- css - 如何在 onclick 事件时将背景颜色更改为反应元素
- javascript - 等待 dTypeError [ERR_INVALID_ARG_TYPE]:“id”参数必须是字符串类型。收到未定义
- ruby-on-rails - 如何在 rubocop 的命名警察中添加到 AllowedNames
- linux - Electron 上的自定义 Linux 桌面环境
- google-sheets - 服务“sheets.googleapis.com”的“每位用户每 100 秒的读取请求”
- javascript - 如何避免库中的默认错误
- node.js - 指定的选择器不匹配 DOM 树中的任何元素
- r - R:河流物种的物种分布建模 - 所有坐标都不落在栅格单元中
- gremlin - 有没有办法知道 gremlin 查询是读查询还是写查询
- mongodb - 在 mongodb 的不同集合中搜索覆盖的字段