--- title: Python Functions description: In Python, A function is a block of organized code that is used to perform a single task. --- ## Function arguments A function can take `arguments` and `return` values: In the following example, the function `say_hello()` receives the argument "name" and prints a greeting: ```python >>> def say_hello(name): ... print('Hello', name) ... >>> say_hello('Carlos') # Hello Carlos >>> say_hello('Wanda') # Hello Wanda >>> say_hello('Rose') # Hello Rose ``` The above function does not return any value (implicitly, it returns `None`) and is called **void function**. The following function, on the other hand, returns values and is thus called the **fruitful** function ```python >>> def my_sum(x,y): ... "Compute x + y." ... return x + y >>> my_sum(1,2) # 3 ``` ## Keyword Arguments When we define functions, we list the input parameters. These are called positional parameters (or positional arguments) because the position in the `def` statement determines which parameter is which. ```python >>> def poly(x,y): ... "Compute x + y**2." ... return x + y**2 >>> poly(1,2) # 5 >>> poly(2,1) # 3 ``` We can set default values for parameters: ```python >>> def psum(x,y,p=2): ... return x**p + y**p >>> psum(1,2) # 5 ``` To improve code readability, we should be as explicit as possible. We can achieve this in our functions by using `Keyword Arguments`: ```python >>> def say_hi(name, greeting): ... print(greeting, name) ... >>> # with positional arguments >>> say_hi('John', 'Hello') # Hello John >>> # with keyword arguments >>> say_hi(name='Anna', greeting='Hi') # Hi Anna ``` ## Return Values When creating a function using the `def` statement, you can specify what the return value should be with a `return` statement. A return statement consists of the following: - The `return` keyword. - The value or expression that the function should return. ```python >>> def sum_two_numbers(number_1, number_2): ... return number_1 + number_2 ... >>> result = sum_two_numbers(7, 8) >>> print(result) # 15 ``` ## Args and Kwargs (Optional) `*args` and `**kwargs` allow you to pass an undefined number of arguments and keywords when calling a function. ```python >>> def some_function(*args, **kwargs): ... pass ... >>> # call some_function with any number of arguments >>> some_function(arg1, arg2, arg3) >>> # call some_function with any number of keywords >>> some_function(key1=arg1, key2=arg2, key3=arg3) >>> # call both, arguments and keywords >>> some_function(arg, key1=arg1) >>> # or none >>> some_function() ``` :::info :bulb: You’ll often see the parameter name `**kwargs` used to collect nonspecific keyword arguments. The `**kwargs` must be the rightmost paramter. ::: ### `*args` Positional arguments through the `*args` variable: ```python >>> def some_function(*args): ... print(f'Arguments passed: {args} as {type(args)}') ... >>> some_function('arg1', 'arg2', 'arg3') # Arguments passed: ('arg1', 'arg2', 'arg3') as <class 'tuple'> ``` ### `**kwargs` Keyword arguments are accessed through the `**kwargs` variable: ```python >>> def some_function(**kwargs): ... print(f'keywords: {kwargs} as {type(kwargs)}') ... >>> some_function(key1='arg1', key2='arg2') # keywords: {'key1': 'arg1', 'key2': 'arg2'} as <class 'dict'> ``` ## Local and Global Scope - Code in the global scope cannot use any local variables. - However, a local scope can access global variables. - Code in a function’s local scope cannot use variables in any other local scope. - You can use the same name for different variables if they are in different scopes. That is, there can be a local variable named `spam` and a global variable also named `spam`. ```python global_variable = 'I am available everywhere' >>> def some_function(): ... print(global_variable) # because is global ... local_variable = "only available within this function" ... print(local_variable) ... >>> # the following code will throw error because >>> # 'local_variable' only exists inside 'some_function' >>> print(local_variable) Traceback (most recent call last): File "<stdin>", line 10, in <module> NameError: name 'local_variable' is not defined ``` ## The `global` Statement If you need to modify a global variable from within a function, use the global statement: ```python >>> def spam(): ... global eggs ... eggs = 'spam' ... >>> eggs = 'global' >>> spam() >>> print(eggs) ``` There are four rules to tell whether a variable is in a local scope or global scope: 1. If a variable is being used in the global scope (that is, outside all functions), then it is always a global variable. 1. If there is a global statement for that variable in a function, it is a global variable. 1. Otherwise, if the variable is used in an assignment statement in the function, it is a local variable. 1. But if the variable is not used in an assignment statement, it is a global variable. ## Importing a module To start importing functions, we first need to create a module. **A module is a file ending in `.py` that contains the code you want to import into your program**. Let’s consider a module that contains the function `make_pizza()`. ### Direct import ```python import pizza pizza.make_pizza(16, 'pepperoni') pizza.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese') ``` ### Importing Specific Functions using `from` ```python from pizza import make_pizza make_pizza(16, 'pepperoni') make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese') ``` ### Using `as` to Give a Function or Module an Alias ``` from pizza import make_pizza as mp mp(16, 'pepperoni') mp(12, 'mushrooms', 'green peppers', 'extra cheese') ``` ### Importing All Functions in a Module ```python from pizza import * make_pizza(16, 'pepperoni') make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese') ``` :::info :bulb: However, it’s best not to use this approach when you’re working with larger modules that you didn’t write: if the module has a function name that matches an existing name in your project, you can get unexpected results! ::: ## Keywords - **divide and conquer (分治法)**: A strategy that breaks a problem into smaller, manageable subproblems, solves each independently, and then combines the results. - **abstraction (抽象化)**: The concept of hiding complex details and showing only the essential features of a process. - **function (函數)**: A reusable block of code designed to perform a specific task when called. - **function call (函數呼叫)**: The act of executing a function by specifying its name along with any required arguments. - **argument (引數)**: The actual value or variable passed to a function when it is called. - **parameter (參數)**: A variable in a function definition that receives the value of an argument when the function is called. - **positional argument (位置參數)**: An argument that must be passed to a function in the correct order as defined by its parameters. - **docstring (文件字串)**: A string placed at the beginning of a function or module to describe its purpose and usage. - **return statement (回傳敘述)**: A statement that ends a function's execution and optionally passes back a value to the caller. - **fruitful function (有回傳值的函數)**: A function that returns a value after execution. - **void function (無回傳值的函數)**: A function that does not return any value. - **keyword argument (關鍵字參數)**: An argument passed to a function by explicitly naming the parameter, allowing arguments to be specified in any order. - **default parameter (預設參數)**: A parameter that has a pre-assigned value, which is used if no argument is provided during the function call. - **local scope (區域)**: The region of a program (typically within a function) where a variable is defined and accessible only within that block. - **global scope (全域)**: The region of a program where variables are accessible from any part of the code, usually defined outside of functions. - **local variable (區域變數)**: A variable defined inside a function that can only be used within that function. - **global variable (全域變數)**: A variable defined at the top level of a module that can be accessed from anywhere within that module. - **module (模組)**: A file containing Python code, such as functions, classes, or variables, that can be imported and reused in other Python programs.