
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 injectedMissing 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 givenThe 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 + bWhat 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.





