2. Placeholder class

2.1. Proxy methods

Listing 419. One of the most common use of *args, **kwargs is for proxy methods.
class Point2D:
    def __init__(self, x, y):
        self.x = x
        self.y = y


class Point3D(Point2D):
    def __init__(self, z, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.z = z

2.2. Flat Problem

DATA = {"sepal_length": 6.0, "sepal_width": 3.4, "petal_length": 4.5, "petal_width": 1.6, "species": "versicolor"},

class Iris:
    def __init__(self, sepal_length, sepal_width, petal_length, petal_width, species):
        self.sepal_length = sepal_length
        self.sepal_width = sepal_width
        self.petal_length = petal_length
        self.petal_width = petal_width
        self.species = species

iris = Iris(**DATA)
iris.species
# 'versicolor'

2.3. Nested Problem

DATA = [
    {"sepal_length": 6.0, "sepal_width": 3.4, "petal_length": 4.5, "petal_width": 1.6, "species": "versicolor"},
    {"sepal_length": 4.9, "sepal_width": 3.1, "petal_length": 1.5, "petal_width": 0.1, "species": "setosa"},
]

class Iris:
    def __init__(self, sepal_length, sepal_width, petal_length, petal_width, species):
        self.sepal_length = sepal_length
        self.sepal_width = sepal_width
        self.petal_length = petal_length
        self.petal_width = petal_width
        self.species = species

    def __repr__(self):
        return f'{self.species}'

flowers = []

for row in DATA:
    iris = Iris(**row)
    flowers.append(iris)

print(flowers)
# ['versicolor', 'setosa']

2.4. Placeholder class

Listing 420. Dynamically creating fields
class MyClass:
    def __init__(self, **kwargs):
        for key, value in kwargs.items():
            setattr(self, key, value)


a = MyClass(first_name='Jan', last_name='Twardowski')
a.first_name          # Jan
a.last_name           # 'Twardowski'

b = MyClass(species='Setosa')
b.species            # 'Setosa'
Listing 421. Dynamically creating fields
class Astronaut:
    def __init__(self, last_name, **kwargs):
        self.last_name = last_name

        for key, value in kwargs.items():
            setattr(self, key, value)


jan = Astronaut(last_name='Twardowski', addresses=())
ivan = Astronaut(first_name='Иван', last_name='Иванович', agency='Roscosmos')

print(jan.last_name)   # Twardowski
print(ivan.first_name)  # Иван

print(jan.__dict__)    # {'last_name': 'Twardowski', 'addresses': ()}
print(ivan.__dict__)    # {'last_name': 'Иванович', 'first_name': 'Иван', 'agency': 'Roscosmos'}
class MyClass:
    def __init__(self, **kwargs):
        self.__dict__ = kwargs


a = MyClass(first_name='Jan', last_name='Twardowski')
print(a.first_name)          # Jan
print(a.last_name)           # 'Twardowski'

b = MyClass(species='Setosa')
print(b.species)             # 'Setosa'
print(b.first_name)          # AttributeError: 'MyClass' object has no attribute 'first_name'
print(b.last_name)           # AttributeError: 'MyClass' object has no attribute 'last_name'