The other answers have done a good job at explaining duck typing and the simple answer by tzot:

Python does not have variables, like other languages where variables have a type and a value; it has names pointing to objects, which know their type.

However, one interesting thing has changed since 2010 (when the question was first asked), namely the implementation of PEP 3107 (implemented in Python 3). You can now actually specify the type of a parameter and the type of the return type of a function like this:

def pick(l: list, index: int) -> int:
    return l[index]

Here we can see that pick takes 2 parameters, a list l and an integer index. It should also return an integer.

So here it is implied that l is a list of integers which we can see without much effort, but for more complex functions it can be a bit confusing as to what the list should contain. We also want the default value of index to be 0. To solve this you may choose to write pick like this instead:

def pick(l: "list of ints", index: int = 0) -> int:
    return l[index]

Note that we now put in a string as the type of l, which is syntactically allowed, but it is not good for parsing programmatically (which we'll come back to later).

It is important to note that Python won't raise a TypeError if you pass a float into index, the reason for this is one of the main points in Python's design philosophy: "We're all consenting adults here", which means you are expected to be aware of what you can pass to a function and what you can't. If you really want to write code that throws TypeErrors you can use the isinstance function to check that the passed argument is of the proper type or a subclass of it like this:

def pick(l: list, index: int = 0) -> int:
    if not isinstance(l, list):
        raise TypeError
    return l[index]

More on why you should rarely do this and what you should do instead is talked about in the next section and in the comments.

PEP 3107 does not only improve code readability but also has several fitting use cases which you can read about here.


Type annotation got a lot more attention in Python 3.5 with the introduction of PEP 484 which introduces a standard module typing for type hints.

These type hints came from the type checker mypy (GitHub), which is now PEP 484 compliant.

The typing module comes with a pretty comprehensive collection of type hints, including:

  • List, Tuple, Set, Dict - for list, tuple, set and dict respectively.
  • Iterable - useful for generators.
  • Any - when it could be anything.
  • Union - when it could be anything within a specified set of types, as opposed to Any.
  • Optional - when it might be None. Shorthand for Union[T, None].
  • TypeVar - used with generics.
  • Callable - used primarily for functions, but could be used for other callables.

These are the most common type hints. A complete listing can be found in the documentation for the typing module.

Here is the old example using the annotation methods introduced in the typing module:

from typing import List

def pick(l: List[int], index: int) -> int:
    return l[index]

One powerful feature is the Callable which allows you to type annotate methods that take a function as an argument. For example:

from typing import Callable, Any, Iterable

def imap(f: Callable[[Any], Any], l: Iterable[Any]) -> List[Any]:
    """An immediate version of map, don't pass it any infinite iterables!"""
    return list(map(f, l))

The above example could become more precise with the usage of TypeVar instead of Any, but this has been left as an exercise to the reader since I believe I've already filled my answer with too much information about the wonderful new features enabled by type hinting.


Previously when one documented Python code with for example Sphinx some of the above functionality could be obtained by writing docstrings formatted like this:

def pick(l, index):
    """
    :param l: list of integers
    :type l: list
    :param index: index at which to pick an integer from *l*
    :type index: int
    :returns: integer at *index* in *l*
    :rtype: int
    """
    return l[index]

As you can see, this takes a number of extra lines (the exact number depends on how explicit you want to be and how you format your docstring). But it should now be clear to you how PEP 3107 provides an alternative that is in many (all?) ways superior. This is especially true in combination with PEP 484 which, as we have seen, provides a standard module that defines a syntax for these type hints/annotations that can be used in such a way that it is unambiguous and precise yet flexible, making for a powerful combination.

In my personal opinion, this is one of the greatest features in Python ever. I can't wait for people to start harnessing the power of it. Sorry for the long answer, but this is what happens when I get excited.


An example of Python code which heavily uses type hinting can be found here.

Answer from erb on Stack Overflow
🌐
GeeksforGeeks
geeksforgeeks.org › python › types-of-arguments-in-python-1
Types of Arguments in Python - GeeksforGeeks
July 23, 2025 - Let’s discuss each type in detail. Default Arguments is a parameter that have a predefined value if no value is passed during the function call. This following example illustrates Default arguments to write functions in Python. ... def calculate_area(length, width=5): area = length * width print(f"Area of rectangle: {area}") # Driver code (We call calculate_area() with only # the length argument) calculate_area(10) # We can also pass a custom width calculate_area(10, 8)
Top answer
1 of 14
1151

The other answers have done a good job at explaining duck typing and the simple answer by tzot:

Python does not have variables, like other languages where variables have a type and a value; it has names pointing to objects, which know their type.

However, one interesting thing has changed since 2010 (when the question was first asked), namely the implementation of PEP 3107 (implemented in Python 3). You can now actually specify the type of a parameter and the type of the return type of a function like this:

def pick(l: list, index: int) -> int:
    return l[index]

Here we can see that pick takes 2 parameters, a list l and an integer index. It should also return an integer.

So here it is implied that l is a list of integers which we can see without much effort, but for more complex functions it can be a bit confusing as to what the list should contain. We also want the default value of index to be 0. To solve this you may choose to write pick like this instead:

def pick(l: "list of ints", index: int = 0) -> int:
    return l[index]

Note that we now put in a string as the type of l, which is syntactically allowed, but it is not good for parsing programmatically (which we'll come back to later).

It is important to note that Python won't raise a TypeError if you pass a float into index, the reason for this is one of the main points in Python's design philosophy: "We're all consenting adults here", which means you are expected to be aware of what you can pass to a function and what you can't. If you really want to write code that throws TypeErrors you can use the isinstance function to check that the passed argument is of the proper type or a subclass of it like this:

def pick(l: list, index: int = 0) -> int:
    if not isinstance(l, list):
        raise TypeError
    return l[index]

More on why you should rarely do this and what you should do instead is talked about in the next section and in the comments.

PEP 3107 does not only improve code readability but also has several fitting use cases which you can read about here.


Type annotation got a lot more attention in Python 3.5 with the introduction of PEP 484 which introduces a standard module typing for type hints.

These type hints came from the type checker mypy (GitHub), which is now PEP 484 compliant.

The typing module comes with a pretty comprehensive collection of type hints, including:

  • List, Tuple, Set, Dict - for list, tuple, set and dict respectively.
  • Iterable - useful for generators.
  • Any - when it could be anything.
  • Union - when it could be anything within a specified set of types, as opposed to Any.
  • Optional - when it might be None. Shorthand for Union[T, None].
  • TypeVar - used with generics.
  • Callable - used primarily for functions, but could be used for other callables.

These are the most common type hints. A complete listing can be found in the documentation for the typing module.

Here is the old example using the annotation methods introduced in the typing module:

from typing import List

def pick(l: List[int], index: int) -> int:
    return l[index]

One powerful feature is the Callable which allows you to type annotate methods that take a function as an argument. For example:

from typing import Callable, Any, Iterable

def imap(f: Callable[[Any], Any], l: Iterable[Any]) -> List[Any]:
    """An immediate version of map, don't pass it any infinite iterables!"""
    return list(map(f, l))

The above example could become more precise with the usage of TypeVar instead of Any, but this has been left as an exercise to the reader since I believe I've already filled my answer with too much information about the wonderful new features enabled by type hinting.


Previously when one documented Python code with for example Sphinx some of the above functionality could be obtained by writing docstrings formatted like this:

def pick(l, index):
    """
    :param l: list of integers
    :type l: list
    :param index: index at which to pick an integer from *l*
    :type index: int
    :returns: integer at *index* in *l*
    :rtype: int
    """
    return l[index]

As you can see, this takes a number of extra lines (the exact number depends on how explicit you want to be and how you format your docstring). But it should now be clear to you how PEP 3107 provides an alternative that is in many (all?) ways superior. This is especially true in combination with PEP 484 which, as we have seen, provides a standard module that defines a syntax for these type hints/annotations that can be used in such a way that it is unambiguous and precise yet flexible, making for a powerful combination.

In my personal opinion, this is one of the greatest features in Python ever. I can't wait for people to start harnessing the power of it. Sorry for the long answer, but this is what happens when I get excited.


An example of Python code which heavily uses type hinting can be found here.

2 of 14
227

Python is strongly typed because every object has a type, every object knows its type, it's impossible to accidentally or deliberately use an object of a type "as if" it was an object of a different type, and all elementary operations on the object are delegated to its type.

This has nothing to do with names. A name in Python doesn't "have a type": if and when a name's defined, the name refers to an object, and the object does have a type (but that doesn't in fact force a type on the name: a name is a name).

A name in Python can perfectly well refer to different objects at different times (as in most programming languages, though not all) -- and there is no constraint on the name such that, if it has once referred to an object of type X, it's then forevermore constrained to refer only to other objects of type X. Constraints on names are not part of the concept of "strong typing", though some enthusiasts of static typing (where names do get constrained, and in a static, AKA compile-time, fashion, too) do misuse the term this way.

🌐
Built In
builtin.com › software-engineering-perspectives › arguments-in-python
5 Types of Python Function Arguments | Built In
Learn about the five different types of arguments used in python function definitions: default, keyword, positional, arbitrary positional and arbitrary keyword arguments. ... In Python, a function is defined with def.
🌐
Python documentation
docs.python.org › 3 › library › typing.html
typing — Support for type hints
February 24, 2026 - The argument list must be a list of types, a ParamSpec, Concatenate, or an ellipsis (...). The return type must be a single type. If a literal ellipsis ... is given as the argument list, it indicates that a callable with any arbitrary parameter list would be acceptable:
🌐
Mimo
mimo.org › glossary › python › parameter
Python Parameters: Essential Coding Know-How | Learn Now
Python parameters allow functions to receive values from a function call. Within the function, parameters become available as variables. Parameters can be of any type, including integers, floats, strings, lists, dictionaries, and even functions.
🌐
Towards Data Science
towardsdatascience.com › home › latest › four types of parameters and two types of arguments in python
Four Types of Parameters and Two Types of Arguments in Python | Towards Data Science
January 29, 2025 - We can add an asterisk in the function parameter list and any parameters to the right can only be passed by keyword argument. def my_func(man1, *, man2): print(man1) print(man2) If we try to use positional arguments for both of them, an error will occur. ... However, if we use keyword argument for man2, there will not be any problems. ... In Python, we can define two types of parameters that have variable lengths.
🌐
GeeksforGeeks
geeksforgeeks.org › python › python-functions
Python Functions - GeeksforGeeks
Below are types of function argument types:. 1. Default Arguments: A default argument is a parameter that assumes a default value if a value is not provided in the function call for that argument. ... 2. Keyword Arguments: values are passed by explicitly specifying the parameter names, so the order doesn’t matter.
Published   2 weeks ago
🌐
Medium
medium.com › @gauravverma.career › parameters-arguments-in-python-function-74a057662c0e
Parameters/Arguments in python function | by Gaurav Verma | Medium
December 7, 2025 - For more details, please refer “user defined functions in python” · ##Function without parameter and no return value def func_without_params_and_return_value(): print("this function does not have parameters") print("this function does not have return value") ##function with two parameter and no return value def my_function(firstname, lastname): print(firstname) print(lastname) ... While defining the function, we can pass the default value to parameter(s) of function in form of <parameter_name> = <default_value>
Find elsewhere
🌐
Hyperskill
hyperskill.org › university › python › parameters-in-python
Parameters in Python
August 15, 2024 - This section explores various types of parameters in Python, including positional parameters, default parameters, keyword parameters, and variable-length parameters.
🌐
Real Python
realpython.com › ref › glossary › parameter
parameter | Python Glossary – Real Python
Positional-only parameters (before / in the signature) can only be passed by position, not by name (Python 3.8+). Keyword-only parameters (after * in the signature) must be passed by name. Parameters with default values have a default value that’s used if no argument is provided. A variable number of parameters enables passing an arbitrary number of arguments to a function.
🌐
Python
peps.python.org › pep-0695
PEP 695 – Type Parameter Syntax | peps.python.org
Type variables can be invariant, covariant, or contravariant. The concept of variance is an advanced detail of type theory that is not well understood by most Python developers, yet they must confront this concept today when defining their first ...
🌐
Codingal
codingal.com › coding-for-kids › blog › python-functions-and-arguments
Python Functions and Arguments | Codingal
November 12, 2025 - In Python, anonymous functions are declared using the lambda keyword, whereas conventional functions are written with the def keyword. Thus, lambda functions are another name for anonymous functions. ... Lambda functions only allow one expression but an unlimited number of parameters.
🌐
W3Schools
w3schools.com › python › python_arguments.asp
Python Function Arguments
A parameter is the variable listed inside the parentheses in the function definition. An argument is the actual value that is sent to the function when it is called. def my_function(name): # name is a parameter print("Hello", name) my_function("Emil") # "Emil" is an argument · By default, a function must be called with the correct number of arguments.
🌐
Hero Vired
herovired.com › learning-hub › topics › arguments-and-parameters-in-python
Arguments and Parameters in Python Functions Simplified
October 23, 2024 - Learn the differences and types of arguments and parameters in Python, including positional, keyword, default, and variable-length arguments.
🌐
W3Schools
w3schools.com › python › python_functions.asp
Python Functions
Python Examples Python Compiler Python Exercises Python Quiz Python Challenges Python Server Python Syllabus Python Study Plan Python Interview Q&A Python Bootcamp Python Certificate Python Training ... A function is a block of code which only runs when it is called.
🌐
Programiz
programiz.com › python-programming › function-argument
Python Function Arguments (With Examples)
Sometimes, we do not know in advance the number of arguments that will be passed into a function. To handle this kind of situation, we can use arbitrary arguments in Python. Arbitrary arguments allow us to pass a varying number of values during a function call. We use an asterisk (*) before the parameter name to denote this kind of argument.
🌐
GeeksforGeeks
geeksforgeeks.org › python › deep-dive-into-parameters-and-arguments-in-python
Python Function Parameters and Arguments - GeeksforGeeks
Python functions can contain two types of arguments: Positional Arguments · Keyword Arguments · Positional Arguments are needed to be included in proper order i.e the first argument is always listed first when the function is called, second argument needs to be called second and so on. Example: Python · def fun(s1,s2): print(s1+s2) fun("Geeks","forGeeks") Output · GeeksforGeeks · Note: The order of arguments must match the order of parameters in the function definition.
Published   July 23, 2025
🌐
Scaler
scaler.com › home › topics › python › python function arguments
Python Function Arguments with Types and Examples - Scaler Topics
November 21, 2023 - In the example above, we provided 5 and 6 as the function arguments for parameters num1 and num2, respectively. There are 4 inherent function argument types in Python, which we can call functions to perform their desired tasks. These are as follows: ... As the name suggests,Default function arguments in Python are some default argument values that we provide to the function at the time of function declaration.
🌐
Alma Better
almabetter.com › bytes › tutorials › python › arguments-in-python-functions
Arguments in Python Functions
April 19, 2024 - On the other hand, parameters are the variables inside the function's parentheses. There are four types of function arguments in Python: required arguments, default arguments, keyword arguments, and arbitrary arguments.
🌐
Codecademy
codecademy.com › learn › flask-introduction-to-python › modules › learn-python3-functions › cheatsheet
Introduction to Python: Functions Cheatsheet | Codecademy
For example, the function definition defines parameters for a character, a setting, and a skill, which are used as inputs to write the first sentence of a book. def write_a_book(character, setting, special_skill): ... Python functions can have multiple parameters.