The general idea is:

def func(arg1, arg2, ..., kwarg1=default, kwarg2=default, ..., *args, **kwargs):
    ...

You can use as many of those as you want. The * and ** will 'soak up' any remaining values not otherwise accounted for.

Positional arguments (provided without defaults) can't be given by keyword, and non-default arguments can't follow default arguments.

Note Python 3 also adds the ability to specify keyword-only arguments by having them after *:

def func(arg1, arg2, *args, kwonlyarg=default):
    ...

You can also use * alone (def func(a1, a2, *, kw=d):) which means that no arguments are captured, but anything after is keyword-only.

So, if you are in 3.x, you could produce the behaviour you want with:

def myFun3(*, name, lname, **other_info):
    ...

Which would allow calling with name and lname as keyword-only.

Note this is an unusual interface, which may be annoying to the user - I would only use it in very specific use cases.

In 2.x, you would need to manually make this by parsing **kwargs.

Answer from Gareth Latty on Stack Overflow
🌐
Real Python
realpython.com › python-kwargs-and-args
Python args and kwargs: Demystified – Real Python
November 7, 2023 - **kwargs works just like *args, but instead of accepting positional arguments it accepts keyword (or named) arguments. Take the following example: ... def concatenate(**kwargs): result = "" # Iterating over the Python kwargs dictionary for arg ...
Discussions

Python class design: explicit keyword arguments vs. **kwargs vs. @property - Stack Overflow
The reason is this: IDEs, automatic documentation generators, code autocompleters, linters, and the like can read a method's argument list. If it's just **kwargs, there's no information there. But if it has the names of the arguments you expect, then these tools can do their work. More on stackoverflow.com
🌐 stackoverflow.com
What are *args and **kwargs ?
Functions take arguments, sometimes you want to be able to pass a dynamic amount of arguments or different arguments - for example a function that adds all arguments passed to it - that's where *args and **kwargs come in. *args is used for passing positional arguments, **kwargs is used for passing keyword arguments. So, if you wanted to write the aforementioned function with *args you would write: def add(*args): return sum(args) #add(1,2,3,4) #10 or to better illustrate what's going on def read_args(*args): for arg in args: print(arg) #read_args(1,2,3,4) #1 #2 #3 #4 The same applies to **kwargs. The important thing to understand here is what's really going on under the hood: passing *args just creates a tuple from all of the positional arguments you pass it, once you understand that, manipulating the arguments is easy. So passing add(1,2,3,4) just means that you end up with a property args with the value of (1,2,3,4). And with kwargs it just converts all of the dynamic keyword arguments you've passed into a dictionary. Meaning passing read_kwargs(one=1, two=2) just leaves you with a property of type dictionary that equals {'one': 1, 'two': 2}. Also an important sidenote is that the keywords args and kwargs isn't important technically - you can name them anything you'd like, the only thing that python is concerned with is the *. Though always use the arg/kwarg as it's convention that's universal at this point. More on reddit.com
🌐 r/learnpython
18
127
November 18, 2017
What is the meaning of the *args and **kwargs arguments in a function definition?
Because as that doc goes on to say, the parameters are not just x and y. They are (x, y) or (y) or (y, fmt) or (x, y, fmt) or (x, y, fmt, x2, y2, fmt2) etc etc etc. And it even carries on to say that x and y don't need to be values to plot at all, but labels for the dict supplied in the data parameter. So the point is that *args allows you to be completely flexible about what positional arguments you accept. More on reddit.com
🌐 r/learnpython
2
1
August 21, 2023
Usage of *args and **kwargs
They have nothing to do with types. They have been in Python long before types were a thing and people were content with duck typing. For *args, just take as example the print function. It takes a variable amount of arguments and concatenates them. There would be no way to replicate that functionality without *args. print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False) Admittedly, use of **kwargs is rarer. One example is in inheritance, where, e.g. the __init__ function, takes the keyword arguments the class knows how to handle, reads them from the dict, and then passes the other kwargs to the next class in the MRO via super. It also is occasionally useful in composition, where the methods of the outer most class recursively calls methods on classes they have references to. E.g. a Screen has an image has a layer has a pixel. The draw method on the screen knows how to handle the **kwds "xpos" and "ypos", the layer knows how to handle the kw "alpha", the pixel knows how to handle the kw "hue" - and all of these are passed down by the individual draw methods as **kwds without the e.g. screen having to know that there even is a "hue" argument. More on reddit.com
🌐 r/learnpython
7
19
June 4, 2022
🌐
GeeksforGeeks
geeksforgeeks.org › python › args-kwargs-python
*args and **kwargs in Python - GeeksforGeeks
This is useful when you want your function to accept flexible, named inputs. Below example shows how **kwargs stores arguments in a dictionary. ... def fun(**kwargs): for k, val in kwargs.items(): print(k, "=", val) fun(s1='Python', s2='is', s3='Awesome')
Published   September 20, 2025
🌐
DigitalOcean
digitalocean.com › community › tutorials › how-to-use-args-and-kwargs-in-python-3
How To Use *args and **kwargs in Python 3 | DigitalOcean
March 6, 2026 - Arguments in a function definition must appear in a strict order. The table below shows the legal order; violating it raises a SyntaxError. Warning: Placing **kwargs before *args raises a SyntaxError immediately. Python rejects the file before running a single line. For example, def f(**kwargs, *args) produces: ... Always follow the legal ordering: standard positional, then *args, then keyword-only, then **kwargs. ... def full_example(name, age, *args, role="user", **kwargs): # name, age: required positional params # *args: captures extra positional values as a tuple # role: keyword-only param with a default # **kwargs: captures extra keyword args as a dict print(f"name={name}, age={age}") print(f"extra positional args: {args}") print(f"role={role}") print(f"extra kwargs: {kwargs}")
🌐
W3Schools
w3schools.com › python › python_args_kwargs.asp
Python *args and **kwargs
*args and **kwargs allow functions to accept a unknown number of arguments. If you do not know how many arguments will be passed into your function, add a * before the parameter name...
🌐
Programiz
programiz.com › python-programming › args-and-kwargs
Python *args and **kwargs (With Examples)
As in the above example we are not sure about the number of arguments that can be passed to a function. Python has *args which allow us to pass the variable number of non keyword arguments to function. In the function, we should use an asterisk * before the parameter name ...
🌐
Thomas Stringer
trstringer.com › python-named-arguments
Why You Should Typically Use Named Arguments in Python | Thomas Stringer
December 27, 2020 - If we had been calling this function with named parameters, then the signature change doesn’t affect the args passed in. Now our original code is resilient to the change, as a is still 1, b is still 2, and c defaults to 3. When working with arguments within a function, it’s easier to reference the argument with the kwargs dictionary than it is with the positional args’ tuple.
Find elsewhere
🌐
Python Tips
book.pythontips.com › en › latest › args_and_kwargs.html
1. *args and **kwargs — Python Tips 0.1 documentation
first normal arg: yasoob another ... allows you to pass keyworded variable length of arguments to a function. You should use **kwargs if you want to handle named arguments in a function....
🌐
The Python Coding Book
thepythoncodingbook.com › home › blog › argh! what are args and kwargs in python? [intermediate python functions series #4]
Argh! What are args and kwargs in Python?
January 18, 2023 - The argument becomes the value associated with that key · There’s nothing special about the name kwargs. As long as you add the double asterisk ** before the parameter name, you can use a more descriptive name · You now know about *args. You also know about **kwargs. Let’s combine both args and kwargs in Python functions.
🌐
SQLPad
sqlpad.io › tutorial › python-kwargs-and-args
Python kwargs and args - Discover Python function arguments. Learn the essentials of *args and **kwargs. Master the art of crafting versatile APIs, handling positional and keyword arguments. - SQLPad.io
Explicitly name keyword arguments when possible: While **kwargs offers flexibility, it can also obscure what arguments a function expects. Where you know the expected keywords, explicitly name them in the function's parameters.
🌐
Towards Data Science
towardsdatascience.com › home › latest › *args, **kwargs & how to specify arguments correctly
*args, **kwargs & How To Specify Arguments Correctly | Towards Data Science
November 26, 2024 - In the same way that positional arguments are related to keyword arguments, *args has a counterpart in *kwargs. It does effectively the same thing as args but instead of being positional arguments, they are named arguments.
🌐
freeCodeCamp
freecodecamp.org › news › args-and-kwargs-in-python
How to Use *args and **kwargs in Python
March 23, 2022 - You can use *args and ****kwargs** as arguments of a function when you are unsure about the number of arguments to pass in the functions. *args allows us to pass a variable number of non-keyword arguments to a Python function.
🌐
Towards Data Science
towardsdatascience.com › home › latest › 10 examples to master *args and **kwargs in python
10 Examples to Master *args and **kwargs in Python | Towards Data Science
January 20, 2025 - If we also pass additional keyword arguments together with a dictionary, they will combined and stored in the kwargs dictionary. dct = {'param1':5, 'param2':8} arg_printer(param3=9, **dct) ...
🌐
Python
peps.python.org › pep-3102
PEP 3102 – Keyword-Only Arguments | peps.python.org
One can easily envision a function which takes a variable number of arguments, but also takes one or more ‘options’ in the form of keyword arguments. Currently, the only way to do this is to define both a varargs argument, and a ‘keywords’ argument (**kwargs), and then manually extract the desired keywords from the dictionary.
🌐
SQL Shack
sqlshack.com › understanding-args-and-kwargs-arguments-in-python
Understanding *args and *kwargs arguments in Python
April 2, 2021 - The positional arguments are defined by the single asterisk before the parameter name, e.g. “*args”. The keyword arguments are defined by placing a double asterisk in front of the parameter name, e.g. “**kwargs”. An important ...
🌐
Scaler
scaler.com › home › topics › python › *args and **kwargs in python
*args and **kwargs in Python - Scaler Topics
November 16, 2023 - *args and **kwargs are special Python keywords that are used to pass the variable length of arguments to a function · When using them together, *args should come before **kwargs · The words “args” and “kwargs” are only conventions.
🌐
Note.nkmk.me
note.nkmk.me › home › python
*args and **kwargs in Python (Variable-Length Arguments) | note.nkmk.me
May 12, 2025 - By convention, *args (arguments) and **kwargs (keyword arguments) are commonly used as parameter names, but you can use any name as long as it is prefixed with * or **. The sample code in this article uses *args and **kwargs.
🌐
Canard Analytics
canardanalytics.com › blog › python-args-and-kwargs
Working with Args and Kwargs in Python | Canard Analytics
July 1, 2022 - When you pass keyword arguments to a function using the **kwargs syntax, the optional keyword arguments are passed into the function as a dictionary with the keyword name as the key and the argument value as the value.
Top answer
1 of 4
20

I'm sure there are many different schools of thought on this, by here's how I've usually thought about it:

Explicit Keyword Arguments

Pros

  • Simple, less code
  • Very explicit, clear what attributes you can pass to the class

Cons

  • Can get very unwieldy as you mention when you have LOTs of things to pass in

Prognosis

This should usually be your method of first attack. If you find however that your list of things you are passing in is getting too long, it is likely pointing to more of a structural problem with the code. Do some of these things you are passing in share any common ground? Could you encapsulate that in a separate object? Sometimes I've used config objects for this and then you go from passing in a gazillion args to passing in 1 or 2

Using **kwargs

Pros

  • Seamlessly modify or transform arguments before passing it to a wrapped system
  • Great when you want to make a variable number of arguments look like part of the api, e.g. if you have a list or dictionary
  • Avoid endlessly long and hard to maintain passthrough definitions to a lower level system,

e.g.

def do_it(a, b, thing=None, zip=2, zap=100, zimmer='okay', zammer=True):
    # do some stuff with a and b
    # ...
    get_er_done(abcombo, thing=thing, zip=zip, zap=zap, zimmer=zimmer, zammer=zammer)

Instead becomes:

def do_it(a, b, **kwargs):
    # do some stuff with a and b
    # ...
    get_er_done(abcombo, **kwargs)

Much cleaner in cases like this, and can see get_er_done for the full signature, although good docstrings can also just list all the arguments as if they were real arguments accepted by do_it

Cons

  • Makes it less readable and explicit what the arguments are in cases where it is not a more or less simple passthrough
  • Can really easily hide bugs and obfuscate things for maintainers if you are not careful

Prognosis

The *args and **kwargs syntax is super useful, but also can be super dangerous and hard to maintain as you lose the explicit nature of what arguments you can pass in. I usually like to use these in situations when I have a method that basically is just a wrapper around another method or system and you want to just pass things through without defining everything again, or in interesting cases where the arguments need to be pre-filtered or made more dynamic, etc. If you are just using it to hide the fact that you have tons and tons of arguments and keyword arguments, **kwargs will probably just exacerbate the problem by making your code even more unwieldy and arcane.

Using Properties

Pros

  • Very explicit
  • Provides a great way of creating objects when they are somehow still "valid" when not all parameters are you known and passing around half-formed objects through a pipeline to slowly populate args. Also for attributes that don't need to be set, but could be, it sometimes provides a clean way of pairing down your __init__'s
  • Are great when you want to present a simple interface of attributes, e.g. for an api, but under the hood are doing more complicated cooler things like maintaining caches, or other fun stuff

Cons

  • A lot more verbose, more code to maintain
  • Counterpoint to above, can introduce danger in allowing invalid objects with some properties not yet fully initialized to be generated when they should never be allowed to exist

Prognosis

I actually really like taking advantage of the getter and setter properties, especially when I am doing tricky stuff with private versions of those attributes that I don't want to expose. It can also be good for config objects and other things and is nice and explicit, which I like. However, if I am initializing an object where I don't want to allow half-formed ones to be walking around and they are serving no purpose, it's still better to just go with explicit argument and keyword arguments.

TL;DR

**kwargs and properties have nice specific use cases, but just stick to explicit keyword arguments whenever practical/possible. If there are too many instance variables, consider breaking up your class into hierarchical container objects.

2 of 4
7

Without really knowing the particulars of your situation, the classic answer is this: if your class initializer requires a whole bunch of arguments, then it is probably doing too much, and it should be factored into several classes.

Take a Car class defined as such:

class Car:
    def __init__(self, tire_size, tire_tread, tire_age, paint_color, 
                 paint_condition, engine_size, engine_horsepower):
        self.tire_size = tire_size
        self.tire_tread = tire_tread
        # ...
        self.engine_horsepower = engine_horsepower

Clearly a better approach would be to define Engine, Tire, and Paint classes (or namedtuples) and pass instances of these into Car():

class Car:
    def __init__(self, tire, paint, engine):
        self.tire = tire
        self.paint = paint
        self.engine = engine

If something is required to make an instance of a class, for example, radius in your Circle class, it should be a required argument to __init__ (or factored into a smaller class which is passed into __init__, or set by an alternative constructor). The reason is this: IDEs, automatic documentation generators, code autocompleters, linters, and the like can read a method's argument list. If it's just **kwargs, there's no information there. But if it has the names of the arguments you expect, then these tools can do their work.

Now, properties are pretty cool, but I'd hesitate to use them until necessary (and you'll know when they are necessary). Leave your attributes as they are and allow people to access them directly. If they shouldn't be set or changed, document it.

Lastly, if you really must have a whole bunch of arguments, but don't want to write a bunch of assignments in your __init__, you might be interested in Alex Martelli's answer to a related question.

🌐
Reddit
reddit.com › r/learnpython › what are *args and **kwargs ?
r/learnpython on Reddit: What are *args and **kwargs ?
November 18, 2017 -

I read few explaination but I just understood they are for variable arguments other than this I am confused

Top answer
1 of 5
85
Functions take arguments, sometimes you want to be able to pass a dynamic amount of arguments or different arguments - for example a function that adds all arguments passed to it - that's where *args and **kwargs come in. *args is used for passing positional arguments, **kwargs is used for passing keyword arguments. So, if you wanted to write the aforementioned function with *args you would write: def add(*args): return sum(args) #add(1,2,3,4) #10 or to better illustrate what's going on def read_args(*args): for arg in args: print(arg) #read_args(1,2,3,4) #1 #2 #3 #4 The same applies to **kwargs. The important thing to understand here is what's really going on under the hood: passing *args just creates a tuple from all of the positional arguments you pass it, once you understand that, manipulating the arguments is easy. So passing add(1,2,3,4) just means that you end up with a property args with the value of (1,2,3,4). And with kwargs it just converts all of the dynamic keyword arguments you've passed into a dictionary. Meaning passing read_kwargs(one=1, two=2) just leaves you with a property of type dictionary that equals {'one': 1, 'two': 2}. Also an important sidenote is that the keywords args and kwargs isn't important technically - you can name them anything you'd like, the only thing that python is concerned with is the *. Though always use the arg/kwarg as it's convention that's universal at this point.
2 of 5
32
It looks like http://book.pythontips.com/en/latest/args_and_kwargs.html explains it pretty well to me.