sm36
sm36

Reputation: 21

How can I pass **kwargs in __init__() constructor in python?

I'm trying to write a program where I am trying to pass **kwargs in init() method. After that when I m trying to make a instance variable inside the constructor(init() method ) , I cant able to make . How can I do this ?

Here is my code :

class Student:
    def __init__(self,**kwargs):
        self.name = name 
        self.age = age
        self.salary = salary

    def show_name(self):
        print("Name is : " + self.name)

    def show_age(self):
        print("Age is : " + str(self.age))

    def show_salary(self):
        print(f"Salary of {self.name} is : " + str(self.salary))


st = Student('John',25,15000)
st2 = Student('Doe',25,1500000)
st.show_salary()
st2.show_salary()

Upvotes: 0

Views: 7510

Answers (3)

Glenn Mackintosh
Glenn Mackintosh

Reputation: 2780

Though you can do this as some of the answers here have shown, this is not really a great idea (at least not for the code you are showing here). So I am not going to answer the subject line question you have asked, but show you what the code you seem to be trying to write should be doing (and that is not using kwargs). There are plenty of places where using kwargs is the best solution to a coding problem, but the constructor of a class is usually not one of those. This is attempting to be teaching, not preaching. I just do not want others coming along later, seeing this question and thinking this is a good idea for a constructor.

The constructor for your class, the __init__(), generally should be defining the parameters that it needs and expects to set up the class. It is unlikely that you really want it to take an arbitrary dictionary to use as its parameter list. It would be relatively rare that this is actually what you want in your constructor, especially when there is no inheritance involved that might suggest you do not know what the parameters are for some reason.

In your __init__() itself you clearly want the parameters name, age and salary, yet without them in the parameter list it is not clear to the caller that you do. Also, your usage of it does not seem to imply that is how you expect to use it. You call it like this:

st = Student('John',25,15000)

and so you do not even seem to want named parameters.

To handle the call structure you have shown the __init__() would look like this:

def __init__(self, name, age, salary):
    self.name = name 
    self.age = age
    self.salary = salary

If you want to be be able to call it without some parameters such that it uses defaults for the ones left out, then it should be like this:

def __init__(self, name=None, age=None, salary=None):
    self.name = name 
    self.age = age
    self.salary = salary

It seems very unlikely that the kwargs approach is really what you want here, though obviously you can code it that way as other answers have shown.

Perhaps you are just trying to figure out how to use kwargs, and that is fine, but a different example would be better if that is the case.

Upvotes: 0

Ashwin
Ashwin

Reputation: 76

kwargs is created as a dictionary inside the scope of the function. You need to pass a keyword which uses them as keys in the dictionary. (Try running the print statement below)

class Student:
    def __init__(self, **kwargs):
        #print(kwargs)
        self.name = kwargs["name"]
        self.age = kwargs["age"]
        self.salary = kwargs["salary"]


    def show_name(self):
        print("Name is : " + self.name)

    def show_age(self):
        print("Age is : " + str(self.age))

    def show_salary(self):
        print(f"Salary of {self.name} is : " + str(self.salary))


st = Student(name = 'John',age = 25, salary = 15000)
st2 = Student(name = 'Doe',age = 25,salary = 1500000)
st.show_salary()
st2.show_salary()

Upvotes: 0

water_ghosts
water_ghosts

Reputation: 736

**kwargs expects arguments to be passed by keyword, not by position. Once you do that, you can access the individual kwargs like you would in any other dictionary:

class Student:
    def __init__(self, **kwargs):
        self.name = kwargs.get('name') 
        self.age = kwargs.get('age')
        self.salary = kwargs.get('salary')

    def show_name(self):
        print("Name is : " + self.name)

    def show_age(self):
        print("Age is : " + str(self.age))

    def show_salary(self):
        print(f"Salary of {self.name} is : " + str(self.salary))


st = Student(name='John', age=25, salary=15000)
st2 = Student(name='Doe', age=25, salary=1500000)
st.show_salary()
st2.show_salary()

If you want to pass these arguments by position, you should use *args instead.

Upvotes: 4

Related Questions