You can use the builtin function vars to get the attributes of most instances as a dictionary. This allows to invoke callables with the attributes, e.g. by using **-unpacking to use them as keyword arguments:
class Car:
def __init__(self, color=None, brand=None, model=None):
self.brand = brand
self.color = color
self.model = model
def print_car(self):
print(
"This is a {color} {brand} manufactured in {model}".format(
**vars(self) # get and unpack attributes to keyword arguments
))
This is not common usage in methods, though it does have its uses. Classes have many capabilities that conflict with explicit destructuring – most importantly subclassing and properties making attributes not strictly defined.
However, classes solely intended to hold a specific set of attributes can be safely destructured. For example, dataclasses directly support converting instances to mappings and sequences. This allows to destructure attributes by name or order.
If destructuring is needed often, it can be automatised using decorators. A simple decorator to destructure the first argument looks like this:
def destruct(method):
"""Mark a method to destructure ``self`` into its arguments"""
@wraps(method)
def wrapper(self, **kwargs):
return method(**vars(self), **kwargs)
return wrapper
It can be applied like other method decorators, e.g. classmethod, directly in the class definition. The method then takes each attribute as a separate argument, instead of the single self argument.
class Car:
def __init__(self, color=None, brand=None, model=None):
self.brand = brand
self.color = color
self.model = model
@destruct
def print_car(color, brand, model):
print(f"This is a {color} {brand} manufactured in {model}")
Car(color='red', brand='audi', model=2001).print_car()
# This is a red audi manufactured in 2001
Note that destruct is a demonstrator. For example, vars does not work for classes using __slots__ – some fallbacks can be used if needed or inspecting the class' __annotations__. Also, the method does not support positional arguments anymore – inspecting the signature or otherwise normalising arguments would allow this.