Fix 'TypeError: method() takes 1 positional argument but 2 were given' in Python

beginner🐍 Python2026-05-25| Python 3.x, All Operating Systems (Windows, Linux, macOS)

Error Message

TypeError: my_method() takes 1 positional argument but 2 were given
#python#oop#typeerror#class

Decoding the Error

It is one of the most common "gotchas" for developers transitioning to Object-Oriented Programming in Python. You call a method with a single value, but Python insists you provided two. The resulting traceback usually looks like this:

Traceback (most recent call last):
  File "app.py", line 12, in <module>
    account.deposit(500)
TypeError: deposit() takes 1 positional argument but 2 were given

The Logic Behind the "Missing" Argument

In 99% of cases, this error happens because you forgot the self parameter in your class method definition. When you call a method on an object instance, Python automatically passes that instance as the very first argument. It does this work behind the scenes so your objects can track their own state.

Take a look at this broken example:

class BankAccount:
    def deposit(amount): # Missing 'self'!
        print(f"Depositing ${amount}")

account = BankAccount()
account.deposit(500)

Even though you only typed 500 inside the parentheses, Python actually executes the call like this: BankAccount.deposit(account, 500). Since your function was defined to only accept one thing (amount), the addition of the account object creates a mismatch.

Three Ways to Fix It

1. The Standard Fix: Adding 'self'

If your method needs to modify or read data from the object—like changing a user's email or a bank balance—you must include self. It acts as a placeholder for whichever specific object is calling the function.

Fixed Code:

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

    # 'self' is the first parameter, 'amount' is the second
    def deposit(self, amount):
        self.balance += amount
        print(f"New balance: ${self.balance}")

account = BankAccount()
account.deposit(500) # Works perfectly now

2. The Utility Fix: Using @staticmethod

Sometimes a function belongs inside a class for organization, but it doesn't actually need to touch any object data. In these cases, use the @staticmethod decorator. This tells Python: "Don't pass the instance to this function."

class ToolBox:
    @staticmethod
    def convert_to_usd(amount, rate):
        return amount * rate

tb = ToolBox()
# No 'self' is passed, so 2 arguments stay 2 arguments
print(tb.convert_to_usd(100, 1.1))

3. The Class-Level Fix: Using @classmethod

Use @classmethod if you need to access the class itself rather than a specific instance. Instead of self, the first argument becomes cls. This is common for creating "factory" methods that generate new objects.

class User:
    def __init__(self, name):
        self.name = name

    @classmethod
    def from_guest_account(cls):
        return cls("Guest") # 'cls' refers to the User class

new_user = User.from_guest_account()

Verifying the Solution

Run your script again after adding self. If you are fixing an instance method, a quick way to verify it is to check if an attribute actually updated. For our bank example, printing account.balance after the call confirms the logic is flowing correctly. If the error persists, double-check that self is truly the first parameter in the list.

Pro-Tips for Clean Code

  • The Name is a Rule: You could technically call self something else, like this or me, but you shouldn't. Stick to self to ensure other developers can read your code without a headache.
  • Check the Constructor: The __init__ method is the most frequent place people forget self. If you miss it there, your code will crash the moment you try to create a new object.
  • Mind Your Decoration: If you find yourself writing a method that never uses self, it's a strong signal that it should probably be a @staticmethod.

Related Error Notes