• Python

Command Palette

Search for a command to run...

Python Fundamentals
  • Python Variables
  • Python Operators
  • Python Input-Output
  • Python Type Conversion
Python Data Types
  • Python Strings
  • Python List
  • Python Tuple
  • Python Dictionnaries
  • Python Sets
Python Flow Control
  • Python Conditions
  • Python For Loop
  • Python While Loop
  • Python Break and Continue
Python Functions
  • Python Functions
  • Python Arguments
  • Python Functions Scope
  • Python Recursion
Python Classes
  • Python Classes
  • Python Classes and Static Methods
  • Python Properties
  • Python Decorators
  • Python Error Handling

Create an Account

FREE

Join our community to access more courses.

Create Account

On this page

Providing Input to FunctionsParameters vs. ArgumentsPositional ArgumentsKeyword ArgumentsDefault Argument ValuesVariable-Length Positional Arguments ()Variable-Length Keyword Arguments ()Forcing Argument Passing Style ( and )
Positional-Only Parameters ()Keyword-Only Parameters ()
Order of Parameters in Function DefinitionArgument Unpacking ( and for Calling)Summary
      • Pricing
      • Blog

      Python Arguments

      Providing Input to Functions

      In the previous article, we learned that functions are reusable blocks of code. To make functions flexible and perform actions on different data, we can pass information into them. These pieces of information are handled by arguments and parameters.

      Understanding how to define and use different types of arguments is essential for writing functions that are powerful, flexible, and easy to use correctly.

      Parameters vs. Arguments

      It's common to hear the terms "parameters" and "arguments" used interchangeably, but in Python, they have distinct meanings:

      • Parameters: These are the names listed in the function definition that specify what kinds of information the function can accept. They are like placeholders for the values the function needs.
        def greet(name): # 'name' is a parameter
            print(f"Hello, {name}!")
        
      • Arguments: These are the actual values you pass to the function when you call it. The arguments are assigned to the corresponding parameters.
        greet("Alice") # "Alice" is an argument
        

      Think of parameters as the variables declared in the function's blueprint, and arguments as the specific values you supply when you build or use that blueprint.

      Positional Arguments

      Positional arguments are the simplest type. When you call a function, you provide values in the same order as the parameters are defined in the function signature. Python matches the arguments to the parameters based solely on their position.

      def describe_pet(animal_type, pet_name):
          print(f"I have a {animal_type}.")
          print(f"My {animal_type}'s name is {pet_name}.")
      
      # The order matters! 'dog' goes to animal_type, 'Buddy' goes to pet_name
      describe_pet('dog', 'Buddy')
      

      Output:

      I have a dog.
      My dog's name is Buddy.
      

      If you change the order, the meaning changes (or you might get an error if types are incompatible):

      describe_pet('Buddy', 'dog')
      

      Output:

      I have a Buddy.
      My Buddy's name is dog.
      

      Keyword Arguments

      With keyword arguments, you specify which parameter each argument should be assigned to by using the parameter name followed by an equals sign (=).

      The main advantage of keyword arguments is that the order does not matter, and the code becomes more readable because the purpose of each argument is clear.

      def describe_pet(animal_type, pet_name):
          print(f"I have a {animal_type}.")
          print(f"My {animal_type}'s name is {pet_name}.")
      
      # Using keyword arguments - order doesn't affect assignment
      describe_pet(pet_name='Hamster', animal_type='rodent')
      

      Output:

      I have a rodent.
      My rodent's name is Hamster.
      

      You can mix positional and keyword arguments in a single call, but all positional arguments must come before any keyword arguments.

      describe_pet('cat', pet_name='Whiskers') # Positional first, then keyword - OK
      
      # describe_pet(pet_name='Whiskers', 'cat') # Keyword first, then positional - ERROR!
      # SyntaxError: positional argument follows keyword argument
      

      Default Argument Values

      You can give a parameter a default value in the function definition. If the caller doesn't provide an argument for that parameter, the default value is used. If an argument is provided, the default is ignored.

      def greet(name, greeting="Hello"):
          print(f"{greeting}, {name}!")
      
      # Using the default greeting
      greet("Alice")
      
      # Providing a different greeting
      greet("Bob", "Hi")
      

      Output:

      Hello, Alice!
      Hi, Bob!
      

      Parameters with default values must come after parameters without default values in the function definition.

      # def invalid_func(greeting="Hello", name): # ERROR! Non-default parameter follows default parameter
      #     print(f"{greeting}, {name}!")
      

      (Brief note: Be cautious using mutable objects like lists or dictionaries as default values, as they can lead to unexpected behavior. For beginner purposes, usually stick to immutable defaults like strings, numbers, or None.)

      Variable-Length Positional Arguments (*args)

      Sometimes, you want a function to accept any number of positional arguments. Python allows this using a parameter prefixed with a single asterisk (*). By convention, this parameter is often named *args.

      When the function is called, all extra positional arguments that are not assigned to named parameters are collected into a tuple and assigned to the *args parameter.

      def sum_all_numbers(*args):
          print(f"args is: {args}") # args is a tuple
          return sum(args)
      
      print(sum_all_numbers(1, 2, 3))         # Output: args is: (1, 2, 3)\n6
      print(sum_all_numbers(10, 20, 30, 40))  # Output: args is: (10, 20, 30, 40)\n100
      print(sum_all_numbers())                # Output: args is: ()\n0
      

      *args must be placed after any standard positional parameters.

      Variable-Length Keyword Arguments (**kwargs)

      Similarly, you might want a function to accept any number of keyword arguments. You can do this using a parameter prefixed with two asterisks (**). By convention, this parameter is often named **kwargs.

      When the function is called, all extra keyword arguments that are not assigned to named parameters are collected into a dictionary and assigned to the **kwargs parameter.

      def print_user_info(**kwargs):
          print(f"kwargs is: {kwargs}") # kwargs is a dictionary
          for key, value in kwargs.items():
              print(f"{key}: {value}")
      
      print_user_info(name="Alice", age=30, city="New York")
      # Output: kwargs is: {'name': 'Alice', 'age': 30, 'city': 'New York'}\nname: Alice\nage: 30\ncity: New York
      
      print_user_info(product="Laptop", price=1200) # Different keywords
      # Output: kwargs is: {'product': 'Laptop', 'price': 1200}\nproduct: Laptop\nprice: 1200
      
      print_user_info() # No keyword arguments
      # Output: kwargs is: {}
      

      **kwargs must be the last parameter in the function definition.

      Forcing Argument Passing Style (/ and *)

      Python offers special syntax to control how callers must pass arguments for certain parameters.

      Positional-Only Parameters (/)

      Parameters listed before a single forward slash (/) can only be passed using their position (as positional arguments). You cannot use their name as a keyword argument.

      def pos_only_example(a, b, /, c, d):
          # a and b are positional-only
          # c and d can be positional or keyword
          print(f"a: {a}, b: {b}, c: {c}, d: {d}")
      
      pos_only_example(1, 2, 3, 4)       # All positional - OK
      pos_only_example(1, 2, c=3, d=4)   # a, b positional; c, d keyword - OK
      pos_only_example(1, 2, 3, d=4)     # a, b, c positional; d keyword - OK
      
      # pos_only_example(a=1, b=2, 3, 4) # ERROR! Cannot use keyword for positional-only
      # TypeError: pos_only_example() got some positional-only arguments passed as keyword arguments: 'a, b'
      
      # pos_only_example(1, b=2, 3, 4) # ERROR! Cannot use keyword for positional-only
      # TypeError: pos_only_example() got some positional-only arguments passed as keyword arguments: 'b'
      

      Positional-only parameters are sometimes used in built-in functions for clarity or to prevent breaking code if parameter names change later.

      Keyword-Only Parameters (*)

      Parameters listed after a single asterisk (*) (or after *args if used) can only be passed using their keyword name. You cannot use their position to pass an argument.

      def kw_only_example(a, b, *, c, d):
          # a and b can be positional or keyword
          # c and d are keyword-only
          print(f"a: {a}, b: {b}, c: {c}, d: {d}")
      
      kw_only_example(1, 2, c=3, d=4)     # a, b positional; c, d keyword - OK
      kw_only_example(a=1, b=2, c=3, d=4) # a, b keyword; c, d keyword - OK
      kw_only_example(1, b=2, c=3, d=4)   # a positional, b keyword; c, d keyword - OK
      
      # kw_only_example(1, 2, 3, 4)       # ERROR! Cannot use positional for keyword-only
      # TypeError: kw_only_example() takes 2 positional arguments but 4 were given
      
      # kw_only_example(1, 2, 3, d=4)     # ERROR! Cannot use positional for keyword-only
      # TypeError: kw_only_example() takes 2 positional arguments but 3 positional arguments (and 1 keyword-only argument) were given
      

      Keyword-only arguments are useful for making function calls clearer (requiring the user to name certain arguments) and for adding new parameters to functions without breaking existing code that calls the function positionally.

      Order of Parameters in Function Definition

      When defining a function that uses multiple types of parameters, they must appear in a specific order:

      • Positional-Only Parameters: Parameters before /.
      • Positional-or-Keyword Parameters: Parameters after / (if used) and before * or *args.
      • *args: The single asterisk parameter for collecting extra positional arguments.
      • Keyword-Only Parameters: Parameters after * (if used) or after *args.
      • **kwargs: The double asterisk parameter for collecting extra keyword arguments.

      Here's a function signature showing all possible types in the correct order:

      def complex_example(pos1, pos2, /, pos_or_kw, *args, kw_only1, kw_only2="default", **kwargs):
          print(f"pos1: {pos1}")
          print(f"pos2: {pos2}")
          print(f"pos_or_kw: {pos_or_kw}")
          print(f"args: {args}")
          print(f"kw_only1: {kw_only1}")
          print(f"kw_only2: {kw_only2}")
          print(f"kwargs: {kwargs}")
      
      # Example call using different argument types
      complex_example(1, 2, 3, 4, 5, kw_only1=6, extra1=7, extra2=8)
      
      # Output:
      # pos1: 1
      # pos2: 2
      # pos_or_kw: 3
      # args: (4, 5)
      # kw_only1: 6
      # kw_only2: default
      # kwargs: {'extra1': 7, 'extra2': 8}
      

      Argument Unpacking (* and ** for Calling)

      You've seen * and ** used in function definitions. They have a different meaning when used in a function call.

      • Using * before an iterable (like a list or tuple) in a function call unpacks its elements and passes them as positional arguments.

        def add(a, b, c):
            return a + b + c
        
        numbers = [1, 2, 3]
        print(add(*numbers)) # Unpacks the list [1, 2, 3] into arguments 1, 2, 3
        # Output: 6
        
        # Can also be used with ranges, tuples, strings, etc.
        print(add(*(range(3, 6)))) # Unpacks the range object
        # Output: 12 (3 + 4 + 5)
        
      • Using ** before a dictionary in a function call unpacks its key-value pairs and passes them as keyword arguments.

        def greet(**kwargs):
            if "name" in kwargs:
                print(f"Hello, {kwargs['name']}!")
            if "message" in kwargs:
                print(kwargs['message'])
        
        info = {"name": "Alice", "message": "Nice to see you!"}
        greet(**info) # Unpacks the dictionary into keyword arguments name='Alice', message='Nice to see you!'
        # Output: Hello, Alice!\nNice to see you!
        

      Argument unpacking is a powerful way to pass data from collections to functions.

      Summary

      • Parameters are in the definition; arguments are the values passed during the call.
      • Positional arguments are matched by order.
      • Keyword arguments are matched by name (name=value); order doesn't strictly matter.
      • Default values provide fallbacks if an argument isn't supplied.
      • *args collects extra positional arguments into a tuple.
      • **kwargs collects extra keyword arguments into a dictionary.
      • Positional-only parameters (before /) must be passed positionally.
      • Keyword-only parameters (after *) must be passed by keyword name.
      • Parameters in definition follow a strict order: positional-only, positional-or-keyword, *args, keyword-only, **kwargs.
      • *iterable and **dictionary can be used in function calls to unpack arguments.

      Understanding these different ways to handle function arguments gives you great flexibility and control when designing and using functions in Python.

      Continue Learning

      Python Variables

      Popular

      Getting Started: Understanding Variables in Python In programming, we often need to store informatio

      Python Strings

      For You

      Working with Text: Understanding Strings in Python Text is everywhere in the world of programming. W

      Python Type Conversion

      For You

      Changing Data Types: Understanding Type Conversion In Python, data has different types like whole nu

      Personalized Recommendations

      Log in to get more relevant recommendations based on your reading history.