top of page
Writer's pictureHui Wang

93. Machine learning: Python Functions (Part 2/2)

1. Inner Functions


An inner function is a function that is defined inside another function. The inner function can access variables and parameters of the outer function, but the outer function cannot access variables and parameters of the inner function. Inner functions are often used to organize code and to avoid naming conflicts between different functions. They can also be used to implement closures, which are a way to retain access to the variables from the enclosing scope even after the outer function has returned.


  • Example:

def outer_function(x):
    def inner_function(y):
        return x + y
    return inner_function

inner = outer_function(3)
result = inner(2)
print(result)  # Output: 5

In this example, the outer_function defines an inner function, inner_function, that takes a single argument, y, and returns the sum of x and y. The outer_function returns the inner_function. The inner function is assigned to the variable inner and it is invoked with the argument 2. The result is the sum 3 + 2 = 5


Inner functions can also be used in closures where the inner function retains access to the variables from the enclosing scope even after the outer function has returned.



2. Keyword Arguments


keyword arguments are a way to pass values to a function by specifying the name of the argument followed by an equal sign and the value. This allows you to specify the arguments in any order, as long as the names match the names of the parameters in the function definition.


  • Example:

def my_function(a, b, c=3):
    print(a, b, c)

my_function(1, 2, c=4)  # Output: 1 2 4
my_function(a=1, c=4, b=2)  # Output: 1 2 4

In this example, the function my_function takes three arguments: a, b, and c. The argument c has a default value of 3, so if it is not specified when the function is called, it will use the default value. In the first function call, the arguments are specified in the order a, b, and c, and the value of c is overridden to 4. In the second function call, the arguments are specified by name, and the order does not matter. Both calls produce the same output.


It's worth noting that in Python 3.8 and later versions, you can use positional-only arguments. These are arguments that can only be passed positionally and not as keyword arguments. This is done by placing a forward slash (/) in the function definition before the first positional-only argument.


  • Positional-only argument


"/" indicates that certain functions' arguments must use positional-only arguments instead of keyword arguments.

def funx(a,b,/): # a and b on the left of "/" are positional-only arguments
     pass

In the following example, a and b are positional-only arguments, c or d can be positional-only arguments or keyword arguments, and e or f are required to be keyword arguments:

def f(a, b, /, c, d, *, e, f):
     print(a, b, c, d, e, f)

The following is a legal call:

f(10, 20, 30, d=40, e=50, f=60)

However, the following are all illegal calls:

f(10, b=20, c=30, d=40, e=50, f=60) # b cannot be a keyword argument
f(10, 20, 30, 40, 50, f=60) # e must be a keyword argument
This


3. Default Arguments


Default arguments are a way to specify a default value for an argument in a function definition. If an argument is not passed to the function when it's called, the default value is used instead.


  • Example:

def my_function(a, b=2, c=3):
    print(a, b, c)

my_function(1)  # Output: 1 2 3
my_function(1, 4)  # Output: 1 4 3

In this example, the function my_function takes three arguments: a, b, and c. The arguments b and c have default values of 2 and 3, respectively, so if they are not specified when the function is called, they will use the default values. In the first function call, the argument a is passed and the second and third arguments are not, so the default values are used. In the second function call, the argument a and b are passed and the third argument is not passed, so the default value is used.


You can also use default arguments along with positional and keyword arguments as well:

def my_function(a, b=2, c=3, *args, **kwargs):
    print(a, b, c, args, kwargs)

my_function(1, 4, c=5, d=6, 7, 8, e=9)
# Output: 1 4 5 (7, 8) {'d': 6, 'e': 9}

In this example, the first three arguments a, b, and c have default values, the rest of the arguments are passed as variable positional arguments (*args) and variable keyword arguments (**kwargs).



4. Variable-length Arguments


Variable-length arguments are a way to pass a variable number of arguments to a function. There are two types of variable-length arguments:


*args: Allows a function to accept any number of positional arguments. These arguments are passed to the function as a tuple.


**kwargs: Allows a function to accept any number of keyword arguments. These arguments are passed to the function as a dictionary.


  • Example:

def my_function(*args, **kwargs):
    print(args)
    print(kwargs)

my_function(1, 2, 3)  # Output: (1, 2, 3) {}
my_function(a=1, b=2, c=3)  # Output: () {'a': 1, 'b': 2, 'c': 3}
my_function(1, 2, 3, a=1, b=2, c=3)  # Output: (1, 2, 3) {'a': 1, 'b': 2, 'c': 3}

In this example, the function my_function takes variable-length arguments *args and **kwargs. The first function call passes three positional arguments, which are collected into the tuple args. The second function call passes three keyword arguments, which are collected into the dictionary kwargs. The third function call passes a combination of both positional and keyword arguments.


It's also worth noting that you can use the * operator to unpack a list or tuple when calling a function with variable-length arguments. For example:

def my_function(*args):
    print(args)

my_list = [1, 2, 3]
my_function(*my_list)  # Output: (1, 2, 3)

In this example, the * operator is used to unpack the elements of the list my_list and pass them as individual positional arguments to the function my_function. This is equivalent to calling my_function(1, 2, 3).


Similarly, you can use the ** operator to unpack a dictionary when calling a function with variable-length keyword arguments. For example:

def my_function(**kwargs):
    print(kwargs)

my_dict = {'a': 1, 'b': 2, 'c': 3}
my_function(**my_dict)  # Output: {'a': 1, 'b': 2, 'c': 3}

In this example, the ** operator is used to unpack the elements of the dictionary my_dict and pass them as individual keyword arguments to the function my_function. This is equivalent to calling my_function(a=1, b=2, c=3).


Variable-length arguments can be useful in many situations, for example, when you want to write a function that can accept a variable number of arguments without knowing in advance how many arguments will be passed. They can also be useful when you want to write a function that can accept any combination of positional and keyword arguments.



5. Lambda Functions


lambda functions are small, anonymous functions that are defined using the lambda keyword. They have a single expression as their body and are often used as a shorthand for a function definition. Lambda functions are useful when you need to pass a small function as an argument to another function or when you want to define a function without giving it a name.


  • Example:

add = lambda x, y: x + y
result = add(3, 4)
print(result)  # Output: 7

In this example, the lambda function takes two arguments x and y and returns their sum. The function is assigned to a variable add and then is invoked with the arguments 3 and 4.


Another example of lambda function is:

squared = lambda x: x*x
result = squared(4)
print(result)  # Output: 16

In this example, the lambda function takes one argument x and returns it's square. The function is assigned to a variable squared and then is invoked with the argument 4.


Lambda functions are commonly used in conjunction with other built-in functions like filter(), map(), and reduce().



6. Callback Function


A callback function is a function that is passed as an argument to another function, and is invoked (or "called back") by that function at a later time. Callback functions are used to extend the functionality of a function without the need to modify its source code.


  • Example:

def my_function(x, callback):
    result = x*x
    callback(result)

def my_callback(result):
    print(result)

my_function(4, my_callback)  # Output: 16

In this example, the my_function takes two arguments, x and callback. my_function calculates the square of x and then invokes the callback function passed in, passing the result as an argument. The my_callback function then prints the result.


Another example of callback function is:

def my_function(x, callback):
    result = x*x*x
    callback(result)

my_callback = lambda result: print(result)

my_function(4, my_callback)  # Output: 64

In this example, my_callback is defined as a lambda function, it takes one argument result and print it. The my_function is invoked with the argument 4 and my_callback as a callback function.


Callback functions can be useful in many situations, for example when you want to write a function that can be extended to handle different use cases without modifying the source code. They can also be useful when you want to pass a function as an argument to another function and have that function execute the passed-in function at a later time, such as in event-driven programming where a certain action triggers a callback function to be executed.


In GUI programming, for example, a button click event can trigger a callback function that performs a specific action, without the need to modify the button click event handling function. In multi-threading, a callback function can be passed as an argument to a function that runs on a separate thread, so that the callback function is executed when the thread completes its task.


Callback functions are also commonly used in functional programming, in libraries like asyncio or concurrent.futures and frameworks like Tornado or Twisted. In these cases, a callback function is passed as an argument to a function that performs an asynchronous task, so that the callback function is executed when the task completes.


In summary, callback functions are a powerful feature in Python, allowing you to extend the functionality of a function, pass functions as arguments and execute them at a later time, in different contexts and with different parameters, making your code more flexible and reusable.


 

Follow me on:

Recent Posts

See All

コメント


bottom of page