__abs__ / __neg__ / __pos__

__abs__(self) | __neg__(self) | __pos__(self)
Returns: Any · Updated March 30, 2026 · Dunder Methods
operators dunder-methods numeric-types

Python calls these three dunder methods automatically when you use unary operators on an object. __abs__ handles abs(), __neg__ handles -, and __pos__ handles +. None take arguments beyond self, and all must return a value — returning None raises TypeError.

abs

Called by the built-in abs() function. For numeric types, return a non-negative representation.

class Temperature:
    def __init__(self, celsius):
        self.celsius = celsius

    def __abs__(self):
        return abs(self.celsius)

t = Temperature(-10)
print(abs(t))  # 10

If __abs__ is not defined, abs() raises TypeError directly — it does not fall back to __neg__.

neg

Called by the unary minus operator -. Must return a value — None raises TypeError.

class Vector:
    def __init__(self, x, y):
        self.x, self.y = x, y

    def __neg__(self):
        return Vector(-self.x, -self.y)

v = Vector(3, -4)
print((-v).x, (-v).y)  # -3 4

pos

Called by the unary plus operator +. Most numeric types return themselves unchanged, but you can define custom behavior.

class Money:
    def __init__(self, amount):
        self.amount = amount

    def __pos__(self):
        return Money(abs(self.amount))

m = Money(-50)
print((+m).amount)  # 50

__pos__ is semantically odd when it changes value. Document the reason clearly if you use it for something other than an identity operation.

Common Mistakes

Returning None

All three methods must return an object. Forgetting return causes TypeError.

class Broken:
    def __neg__(self):
        pass  # missing return

# -Broken()  # TypeError

abs does not fall back to neg

abs(obj) raises TypeError if __abs__ is missing — it does not call __neg__. These are separate protocols.

class NoAbs:
    def __neg__(self):
        return self

# abs(NoAbs())  # TypeError
# -NoAbs()      # works

NotImplemented is for binary operators only

NotImplemented has no meaning for unary operators. Returning it from __abs__, __neg__, or __pos__ immediately raises TypeError. It only applies to binary operators where Python tries a reflected version.

Type inconsistency

Python does not enforce that __abs__ returns the same type as self. Returning a plain int from a custom class is legal, but later arithmetic will fail with confusing errors.

class Bad:
    def __abs__(self):
        return 42  # returns int, not Bad

b = Bad()
result = abs(b)  # 42
# result + b  # TypeError

See Also

  • add — binary addition
  • eq — equality comparison

Summary

MethodOperatorExpected Return
__abs__abs()Non-negative value
__neg__-Negated value
__pos__+Positive value

All three take only self. All three must return a value — None is not allowed. If you omit any of these, the corresponding operation raises TypeError with no fallback to another method.