Search code examples
pythonpython-3.xkeyword-argument

Trying to use **kwargs to define attributes in a class


So I have a class that defines characters and its attributes and it goes like this:

class character():

    def __init__(self, health, dodge, damage, critAdd):

        self.health=health
        self.dodge=dodge
        self.damage=damage
        self.critAdd=critAdd

and when I create an instance as this:

knight=character(150, 5, 40, 1.5)

it works perfectly. But what I´m trying to create is a way of creating it with key values, like this:

knight=character(health=150, dodge=5, damage=40, critAdd=1.5)

So i tried to write the __init__ like this, using **kwargs:

def __init__(self, **kwargs):

    self.health=health
    self.dodge=dodge
    self.damage=damage
    self.critAdd=critAdd

It says:

NameError: name 'health' is not defined

What am I doing wrong? I´m really new to programming so I can´t figure it out.


Solution

  • kwargs is just a mapping; it doesn't magically create local variables for your function. You need to index the python dictionary with the desired key.

    def __init__(self, **kwargs):
        self.health = kwargs['health']
        self.dodge = kwargs['dodge']
        self.damage = kwargs['damage']
        self.critAdd = kwargs['critAdd']
    

    A dataclass simplifies this:

    from dataclasses import dataclass
    
    @dataclass
    class Character:
        health: int
        dodge: int
        damage: int
        critAdd: float
    

    This generates your original __init__ automatically.

    If you need to do additional work in __init__ after adding the dataclass decorator you can define __post_init__ which a dataclass will call after __init__.