How to Fix: TypeError: method takes 1 positional argument but 2 were given

3D isometric illustration of a robot causing an error by trying to push an extra argument into a method machine whose only slot is occupied by 'self', next to a corrected version with an open slot.

You called my_object.method(x) and passed one argument. Python counted two. The second argument is the instance itself — Python injected it automatically, and your method definition has nowhere to receive it. This is a common cause of the TypeError method takes 1 positional argument error in Python.

⚡ Quick Fix: TypeError method() Takes 1 Positional Argument but 2 Were Given

Python injected the instance as the first argument automatically — your method definition is missing self to receive it.

# Fix 1 — Add self as the first parameter in every instance method
class Dog:
    def bark(self, volume):
        print(f"Barking at volume {volume}")

fido = Dog()
fido.bark("loud")  # Works

# Fix 2 — No instance needed: use @staticmethod to skip self entirely
class Calculator:
    @staticmethod
    def add(a, b):
        return a + b

Calculator.add(2, 3)  # Works — no self injected

Missing self is the common trigger — but inheritance overrides and @classmethod misuse produce the same error through different paths, and the traceback rarely points at the right line.

The Cause: The Invisible self

When you call a method on an object (my_obj.func(arg)), Python automatically converts it to: Class.func(my_obj, arg)

It passes the object itself (my_obj) as the first argument.

If your function definition didn’t expect that first argument, it crashes.

Problem Code:

class Dog:
    # Oops! Forgot 'self'
    def bark(volume):
        print(f"Barking at volume {volume}")

fido = Dog()
# We pass 1 argument ("loud")
# Python passes 2 arguments (fido, "loud")
fido.bark("loud") 
# CRASH! TypeError: bark() takes 1 positional argument but 2 were given

The Fix: Add self

You must always include self as the first argument in standard class methods.

Correct Code:

class Dog:
    # Correct!
    def bark(self, volume):
        print(f"Barking at volume {volume}")

fido = Dog()
fido.bark("loud") # Works!

Exception: Static Methods

If you don’t want the function to receive the object (no self), use the @staticmethod decorator.

class Calculator:
    @staticmethod
    def add(a, b): # No self needed!
        return a + b

What This Error Exposes About Python’s Descriptor Protocol and Method Binding

TypeError: method() takes 1 positional argument but 2 were given surfaces a mechanism most Python developers use daily without ever examining — the descriptor protocol. When you access a method through an instance (fido.bark), Python does not return the raw function. It returns a bound method object — a wrapper that permanently attaches the instance to the function’s first argument slot. Every subsequent call through that bound method automatically prepends the instance, which is why fido.bark("loud") delivers two arguments to a function that only declared one parameter.

The @staticmethod decorator exits the descriptor protocol entirely. It wraps the function in a descriptor that suppresses the automatic instance injection, returning the raw function unchanged whether accessed through the class or an instance. @classmethod takes a different path — it injects the class itself rather than the instance as the first argument, conventionally named cls. Understanding all three method types — instance methods with self, class methods with cls, and static methods with neither — determines which data your method can access and how Python routes calls to it.

The error becomes harder to diagnose in inheritance chains and mixins. A subclass that overrides a parent method but drops self from the signature produces the same error, but the traceback points at the parent’s call site rather than the subclass definition where the parameter was removed. For large class hierarchies, inspect.signature(MyClass.method) reveals the full parameter list of any method at runtime without executing it — a faster diagnostic than reading through multiple levels of inheritance to find where self went missing.


Python Pro Hub readers also found these helpful:

Similar Posts

Leave a Reply