簡體   English   中英

OOP:如何編寫類之間的 Pythonic 交互?

[英]OOP: How to write pythonic interaction between classes?

我想對兩個類之間的交互進行建模,其中一個類將另一個類作為其方法之一中的參數。 哪個類應該在另一個類的方法的參數中?

我已經為該問題編寫了兩種替代解決方案,但我不確定其中哪一種被認為是處理此問題的正確方法。 也許還有更好的方法,但這是我的兩種選擇:

class BankAccount:

    def __init__(self, balance):
        self._balance = balance

    def transaction(self, cash):
        self._balance += cash._value
        cash._value = 0


class Cash:

    def __init__(self, value):
        self._value = value

    def transfer(self, bank_account):
        bank_account._balance += self._value
        self._value = 0


if __name__ == "__main__":

# First alternative
    acc = BankAccount(balance=100)
    cash = Cash(value=10)

    print('-' * 30)
    print('First alternative')
    print(f'Account balance before: {acc._balance}')
    print(f'Cash value before: {cash._value}')
    acc.transaction(cash=cash)
    print(f'Account balance after: {acc._balance}')
    print(f'Cash value after: {cash._value}')

# Second alternative
    acc = BankAccount(balance=100)
    cash = Cash(value=10)

    print('-' * 30)
    print('Second alternative')
    print(f'Account balance before: {acc._balance}')
    print(f'Cash value before: {cash._value}')
    cash.transfer(bank_account=acc)
    print(f'Account balance after: {acc._balance}')
    print(f'Cash value after: {cash._value}')

正如您所看到的,兩種替代方案都顯示了相同的結果,但我很高興得到有關建模這種類交互的 Pythonic 方式的建議。 謝謝。

該示例格式不正確,這使我們無法專注於實際的 OOP。 一些現金因為被轉移而失去價值是沒有意義的。 20 美元的鈔票是否會因為您將其存入銀行而貶值?

一個新的例子

相反,讓我們考慮代表兩個銀行賬戶之間的匯款的問題。

OOP 的一個關鍵概念是不應直接更新實例的屬性。 相反,該實例應該通過提供對其狀態進行某種控制的方法來提供 API。

我們可以通過為BankAccount定義depositwithdraw方法來實現這一點。 這樣,我們就可以定義只使用該 API 的transfer_to方法。

class BankAccount:
    def __init__(self):
        self.balance = 0

    def deposit(self, amount):
        self.balance += amount

    def withdraw(self, amount):
        if amount >= self.balance:
            self.balance -= amount
        else:
            raise ValueError('Insufficient funds')

    def transfer_to(self, target, amount):
        if isinstance(target, BankAccount):
            self.withdraw(amount)
            target.deposit(amount)
        else:
            raise ValueError("'target' must be another BankAccount")

優勢

通過封裝withdrawdeposittranfer_to的邏輯,我們允許通過繼承來簡單實現更復雜的賬戶類型。

這里讓我們舉一個允許負余額的新型BankAccount的例子。

class CreditAccount(BankAccount):
    def withdraw(self, amount):
        self._balance -= amount

通過將取款的責任完全委托給BankAccount實例,我們允許外部代理操縱帳戶而不必了解取款和存款的內部邏輯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM