Function attributes in Python

written on October 15, 2017

It's well known that in Python, every function is a first-class object, which gives us the ability to pass them as arguments, assign to variables, compare to each other and return from other functions. But what about rarely used custom function attributes?

Function attributes

Every function has a number of additional attributes which can be accessed using dot syntax (e.g. func.__name__). The dir built-in function returns a list of available attributes of a specified object.

Since Python 2.1, functions can have arbitrary attributes, that is, you can use a function as key-value storage.

def func():
    print(func.a)
    func.a -= 10


func.a = 10
func.foo = "bar"
func()
func.a += 2
func()
print(func.__dict__)

Internally, it's just a dictionary that handles failed attribute lookups (i.e., nondefault attributes). You can access or even replace such dictionary using __dict__ attribute. PEP 232 has an extensive description of this feature.

For example, you can track the number of times a function was called:

def func(a, b):
    func.ncalls += 1
    return a + b


func.ncalls = 0

func(1, 2)
func(3, 2)
print(func.ncalls)
Category: python