Ошибка типа: объект не поддерживает индексацию

#python #python-3.x

#питон #python-3.x

Вопрос:

Я недавно изучил Python. Я не могу поймать ошибку в этом коде. Что случилось?

 class BankAccount:

    def __init__(self, initial_balance):
        """Creates an account with the given balance."""
        self  = [initial_balance, 0]

    def deposit(self, amount):
        """Deposits the amount into the account."""
        self  = amount

    def withdraw(self, amount):
        """
        Withdraws the amount from the account.  Each withdrawal resulting in a
        negative balance also deducts a penalty fee of 5 dollars from the balance.
        """
        self[0] -= amount
        if self[0] < 0:
            self[0] -= 5

        self[1]  = 1

    def get_balance(self):
        """Returns the current balance in the account."""
        return self[0]

    def get_fees(self):
        """Returns the total fees ever deducted from the account."""
        return 5*self[1]


my_account = BankAccount(10)
my_account.withdraw(15)
my_account.deposit(20)
my_account.get_balance(), my_account.get_fees()
 

Ошибка заключается в следующем:

 Traceback (most recent call last):
  File "C:Python34bank.py", line 28, in <module>
    my_account.withdraw(15)
  File "C:Python34bank.py", line 15, in withdraw
    self[0] -= amount   5
TypeError: 'BankAccount' object does not support indexing
 

self значение содержит initial_balance и подсчитывает, сколько было снято средств.

Комментарии:

1. Вы делаете ООП на Python совершенно неправильно. Я предлагаю вам прочитать руководство по классам . Кроме того, не могли бы вы, пожалуйста, просмотреть отступ в вашем вопросе?

2. только короткое предложение, прежде чем мои глаза начнут кровоточить, попробуйте использовать self.account во всех местах, где вы написали self (кроме 1-го аргумента в каждом методе, конечно)

3. извините. спасибо за совет

Ответ №1:

self всегда ссылается на объект, который вызывает функцию класса. Поэтому рекомендуется не присваивать переменной self что-либо вроде:

 self = #something
 

в конструкторе. Дайте этой переменной имя. Нравится:

 self.details = [initialbalance,0]
 

И используйте имя переменной везде, где угодно.

Комментарии:

1. Ну, вы можете , но, вероятно, не должны! Кроме того, отдельные атрибуты self.balance и self.withdrawals были бы более разумными.

Ответ №2:

Это должно выглядеть примерно так:

 class BankAccount:

    OVERDRAW_PENALTY = 5

    def __init__(self, opening_balance=0):
        self.balance = opening_balance
        self.withdrawals = 0

    def withdraw(self, amount):
        self.withdrawals  = 1
        self.balance -= amount
        if self.balance < 0:
            self.balance -= self.OVERDRAW_PENALTY
        return amount
 

Обратите внимание, что я использую self для доступа к атрибутам экземпляра и класса, а не пытаюсь присвоить ему напрямую. Кроме того, я учел «магическое число» 5 , чтобы было понятнее, что происходит.

Кроме того, ваша реализация get_fees неверна — количество изъятий в настоящее время увеличивается независимо от того, применяется плата или нет. Вы должны либо сохранить self.overdrawn_withdrawals счетчик отдельно, либо сохранить текущий self.fees атрибут total.

Наконец, я добавил return amount в конец withdraw — это позволяет вам делать такие вещи, как:

 account2.deposit(account1.withdraw(100))
 

чтобы легко переводить деньги между BankAccount s.

Ответ №3:

self ссылается на объект BankAccount . Вам необходимо назначить переменные экземпляра и ссылаться на них.

Ваш __init__() метод должен быть примерно таким:

 class BankAccount:
    def __init__(self, initial_balance):
        """Creates an account with the given balance."""
        self.balance  = initial_balance
        self.fees = 0
        self.withdrawals = 0

    def deposit(self, amount):
        """Deposits the amount into the account."""
        self.balance  = amount
 

Точно withdraw() так же и get_balance() следует ссылаться self.balance , и get_fees() следует ссылаться self.fees .