learn-python
123 строки · 5.3 Кб
1"""Function Definition
2
3@see: https://docs.python.org/3/tutorial/controlflow.html#defining-functions
4@see: https://www.thecodeship.com/patterns/guide-to-python-function-decorators/
5
6The keyword def introduces a function definition. It must be followed by the function name and the
7parenthesized list of formal parameters. The statements that form the body of the function start at
8the next line, and must be indented.
9"""
10
11
12def fibonacci_function_example(number_limit):
13"""Generate a Fibonacci series up to number_limit.
14
15The first statement of the function body can optionally be a string literal; this string
16literal is the function’s documentation string, or docstring. There are tools which use
17docstrings to automatically produce online or printed documentation, or to let the user
18interactively browse through code; it’s good practice to include docstrings in code that you
19write, so make a habit of it.
20"""
21
22# The execution of a function introduces a new symbol table used for the local variables of the
23# function. More precisely, all variable assignments in a function store the value in the local
24# symbol table; whereas variable references first look in the local symbol table, then in the
25# local symbol tables of enclosing functions, then in the global symbol table, and finally in
26# the table of built-in names. Thus, global variables cannot be directly assigned a value
27# within a function (unless named in a global statement), although they may be referenced.
28fibonacci_list = []
29previous_number, current_number = 0, 1
30while previous_number < number_limit:
31# The statement result.append(a) calls a method of the list object result. A method is a
32# function that ‘belongs’ to an object and is named obj.methodname, where obj is some
33# object (this may be an expression), and methodname is the name of a method that is
34# defined by the object’s type. Different types define different methods. Methods of
35# different types may have the same name without causing ambiguity. (It is possible to
36# define your own object types and methods, using classes, see Classes) The method
37# append() shown in the example is defined for list objects; it adds a new element at
38# the end of the list. In this example it is equivalent to result = result + [a], but
39# more efficient.
40fibonacci_list.append(previous_number)
41# This is multiple assignment statement. We make current number to be previous one and the
42# sum of previous and current to be a new current.
43previous_number, current_number = current_number, previous_number + current_number
44
45# The return statement returns with a value from a function. return without an expression
46# argument returns None. Falling off the end of a function also returns None.
47return fibonacci_list
48
49
50def test_function_definition():
51"""Function Definition"""
52
53# Now call the function we just defined.
54assert fibonacci_function_example(300) == [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233]
55
56# A function definition introduces the function name in the current symbol table. The value of
57# the function name has a type that is recognized by the interpreter as a user-defined function.
58# This value can be assigned to another name which can then also be used as a function. This
59# serves as a general renaming mechanism
60fibonacci_function_clone = fibonacci_function_example
61assert fibonacci_function_clone(300) == [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233]
62
63# In Python, functions are first class citizens, they are objects and that means we can do a
64# lot of useful stuff with them.
65
66# Assign functions to variables.
67
68def greet(name):
69return 'Hello, ' + name
70
71greet_someone = greet
72
73assert greet_someone('John') == 'Hello, John'
74
75# Define functions inside other functions.
76
77def greet_again(name):
78def get_message():
79return 'Hello, '
80
81result = get_message() + name
82return result
83
84assert greet_again('John') == 'Hello, John'
85
86# Functions can be passed as parameters to other functions.
87
88def greet_one_more(name):
89return 'Hello, ' + name
90
91def call_func(func):
92other_name = 'John'
93return func(other_name)
94
95assert call_func(greet_one_more) == 'Hello, John'
96
97# Functions can return other functions. In other words, functions generating other functions.
98
99def compose_greet_func():
100def get_message():
101return 'Hello there!'
102
103return get_message
104
105greet_function = compose_greet_func()
106assert greet_function() == 'Hello there!'
107
108# Inner functions have access to the enclosing scope.
109
110# More commonly known as a closure. A very powerful pattern that we will come across while
111# building decorators. Another thing to note, Python only allows read access to the outer
112# scope and not assignment. Notice how we modified the example above to read a "name" argument
113# from the enclosing scope of the inner function and return the new function.
114
115def compose_greet_func_with_closure(name):
116def get_message():
117return 'Hello there, ' + name + '!'
118
119return get_message
120
121greet_with_closure = compose_greet_func_with_closure('John')
122
123assert greet_with_closure() == 'Hello there, John!'
124