Skip to content

Commit a83a9cf

Browse files
committed
Many edits
1 parent 9572f70 commit a83a9cf

23 files changed

+467
-210
lines changed

Notes/07_Advanced_Topics/01_Variable_arguments.md

+37-18
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,31 @@
1+
2+
[Contents](../Contents) \| [Previous (6.4 Generator Expressions)](../06_Generators/04_More_generators) \| [Next (7.2 Anonymous Functions)](02_Anonymous_function)
3+
14
# 7.1 Variable Arguments
25

6+
This section covers variadic function arguments, sometimes described as
7+
`*args` and `**kwargs`.
8+
39
### Positional variable arguments (*args)
410

511
A function that accepts *any number* of arguments is said to use variable arguments.
612
For example:
713

814
```python
9-
def foo(x, *args):
15+
def f(x, *args):
1016
...
1117
```
1218

1319
Function call.
1420

1521
```python
16-
foo(1,2,3,4,5)
22+
f(1,2,3,4,5)
1723
```
1824

19-
The arguments get passed as a tuple.
25+
The extra arguments get passed as a tuple.
2026

2127
```python
22-
def foo(x, *args):
28+
def f(x, *args):
2329
# x -> 1
2430
# args -> (2,3,4,5)
2531
```
@@ -30,45 +36,60 @@ A function can also accept any number of keyword arguments.
3036
For example:
3137

3238
```python
33-
def foo(x, y, **kwargs):
39+
def f(x, y, **kwargs):
3440
...
3541
```
3642

3743
Function call.
3844

3945
```python
40-
foo(2,3,flag=True,mode='fast',header='debug')
46+
f(2, 3, flag=True, mode='fast', header='debug')
4147
```
4248

4349
The extra keywords are passed in a dictionary.
4450

4551
```python
46-
def foo(x, y, **kwargs):
52+
def f(x, y, **kwargs):
4753
# x -> 2
4854
# y -> 3
49-
# kwargs -> { 'flat': True, 'mode': 'fast', 'header': 'debug' }
55+
# kwargs -> { 'flag': True, 'mode': 'fast', 'header': 'debug' }
5056
```
5157

5258
### Combining both
5359

54-
A function can also combine any number of variable keyword and non-keyword arguments.
55-
Function definition.
60+
A function can also accept any number of variable keyword and non-keyword arguments.
5661

5762
```python
58-
def foo(*args, **kwargs):
63+
def f(*args, **kwargs):
5964
...
6065
```
6166

62-
This function takes any combination of positional or keyword arguments.
63-
It is sometimes used when writing wrappers or when you want to pass arguments through to another function.
67+
Function call.
68+
69+
```python
70+
f(2, 3, flag=True, mode='fast', header='debug')
71+
```
72+
73+
The arguments are separated into positional and keyword components
74+
75+
```python
76+
def f(*args, **kwargs):
77+
# args = (2, 3)
78+
# kwargs -> { 'flag': True, 'mode': 'fast', 'header': 'debug' }
79+
...
80+
```
81+
82+
This function takes any combination of positional or keyword
83+
arguments. It is sometimes used when writing wrappers or when you
84+
want to pass arguments through to another function.
6485

6586
### Passing Tuples and Dicts
6687

6788
Tuples can be expanded into variable arguments.
6889

6990
```python
7091
numbers = (2,3,4)
71-
foo(1, *numbers) # Same as f(1,2,3,4)
92+
f(1, *numbers) # Same as f(1,2,3,4)
7293
```
7394

7495
Dictionaries can also be expaded into keyword arguments.
@@ -79,12 +100,10 @@ options = {
79100
'delimiter' : ',',
80101
'width' : 400
81102
}
82-
foo(data, **options)
83-
# Same as foo(data, color='red', delimiter=',', width=400)
103+
f(data, **options)
104+
# Same as f(data, color='red', delimiter=',', width=400)
84105
```
85106

86-
These are not commonly used except when writing library functions.
87-
88107
## Exercises
89108

90109
### Exercise 7.1: A simple example of variable arguments

Notes/07_Advanced_Topics/02_Anonymous_function.md

+14-7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
[Contents](../Contents) \| [Previous (7.1 Variable Arguments)](01_Variable_arguments) \| [Next (7.3 Returning Functions)](03_Returning_functions)
2+
13
# 7.2 Anonymous Functions and Lambda
24

35
### List Sorting Revisited
@@ -30,7 +32,9 @@ It seems simple enough. However, how do we sort a list of dicts?
3032

3133
By what criteria?
3234

33-
You can guide the sorting by using a *key function*. The *key function* is a function that receives the dictionary and returns the value in a specific key.
35+
You can guide the sorting by using a *key function*. The *key
36+
function* is a function that receives the dictionary and returns the
37+
value of interest for sorting.
3438

3539
```python
3640
def stock_name(s):
@@ -39,7 +43,7 @@ def stock_name(s):
3943
portfolio.sort(key=stock_name)
4044
```
4145

42-
The value returned by the *key function* determines the sorting.
46+
Here's the result.
4347

4448
```python
4549
# Check how the dictionaries are sorted by the `name` key
@@ -56,13 +60,16 @@ The value returned by the *key function* determines the sorting.
5660

5761
### Callback Functions
5862

59-
Callback functions are often short one-line functions that are only used for that one operation. For example of previous sorting example.
60-
Programmers often ask for a short-cut, so is there a shorter way to specify custom processing for `sort()`?
63+
In the above example, the key function is an example of a callback
64+
function. The `sort()` method "calls back" to a function you supply.
65+
Callback functions are often short one-line functions that are only
66+
used for that one operation. Programmers often ask for a short-cut
67+
for specifying this extra processing.
6168

6269
### Lambda: Anonymous Functions
6370

64-
Use a lambda instead of creating the function.
65-
In our previous sorting example.
71+
Use a lambda instead of creating the function. In our previous
72+
sorting example.
6673

6774
```python
6875
portfolio.sort(key=lambda s: s['name'])
@@ -156,6 +163,6 @@ Try sorting the portfolio according to the price of each stock
156163

157164
Note: `lambda` is a useful shortcut because it allows you to
158165
define a special processing function directly in the call to `sort()` as
159-
opposed to having to define a separate function first (as in part a).
166+
opposed to having to define a separate function first.
160167

161168
[Contents](../Contents) \| [Previous (7.1 Variable Arguments)](01_Variable_arguments) \| [Next (7.3 Returning Functions)](03_Returning_functions)

Notes/07_Advanced_Topics/03_Returning_functions.md

+19-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
[Contents](../Contents) \| [Previous (7.2 Anonymous Functions)](02_Anonymous_function) \| [Next (7.4 Decorators)](04_Function_decorators)
2+
13
# 7.3 Returning Functions
24

3-
This section introduces the idea of closures.
5+
This section introduces the idea of using functions to create other functions.
46

57
### Introduction
68

@@ -27,7 +29,8 @@ Adding 3 4
2729

2830
### Local Variables
2931

30-
Observe how to inner function refers to variables defined by the outer function.
32+
Observe how to inner function refers to variables defined by the outer
33+
function.
3134

3235
```python
3336
def add(x, y):
@@ -38,7 +41,8 @@ def add(x, y):
3841
return do_add
3942
```
4043

41-
Further observe that those variables are somehow kept alive after `add()` has finished.
44+
Further observe that those variables are somehow kept alive after
45+
`add()` has finished.
4246

4347
```python
4448
>>> a = add(3,4)
@@ -51,7 +55,7 @@ Adding 3 4 # Where are these values coming from?
5155

5256
### Closures
5357

54-
When an inner function is returned as a result, the inner function is known as a *closure*.
58+
When an inner function is returned as a result, that inner function is known as a *closure*.
5559

5660
```python
5761
def add(x, y):
@@ -62,7 +66,10 @@ def add(x, y):
6266
return do_add
6367
```
6468

65-
*Essential feature: A closure retains the values of all variables needed for the function to run properly later on.*
69+
*Essential feature: A closure retains the values of all variables
70+
needed for the function to run properly later on.* Think of a
71+
closure as a function plus an extra environment that holds the values
72+
of variables that it depends on.
6673

6774
### Using Closures
6875

@@ -99,7 +106,7 @@ Closures carry extra information around.
99106
```python
100107
def add(x, y):
101108
def do_add():
102-
print('Adding %s + %s -> %s' % (x, y, x + y))
109+
print(f'Adding {x} + {y} -> {x+y}')
103110
return do_add
104111

105112
def after(seconds, func):
@@ -110,8 +117,6 @@ after(30, add(2, 3))
110117
# `do_add` has the references x -> 2 and y -> 3
111118
```
112119

113-
A function can have its own little environment.
114-
115120
### Code Repetition
116121

117122
Closures can also be used as technique for avoiding excessive code repetition.
@@ -122,11 +127,12 @@ You can write functions that make code.
122127
### Exercise 7.7: Using Closures to Avoid Repetition
123128

124129
One of the more powerful features of closures is their use in
125-
generating repetitive code. If you refer back to exercise 5.2
126-
recall the code for defining a property with type checking.
130+
generating repetitive code. If you refer back to [Exercise
131+
5.7](../05_Object_model/02_Classes_encapsulation), recall the code for
132+
defining a property with type checking.
127133

128134
```python
129-
class Stock(object):
135+
class Stock:
130136
def __init__(self, name, shares, price):
131137
self.name = name
132138
self.shares = shares
@@ -173,7 +179,7 @@ Now, try it out by defining a class like this:
173179
```python
174180
from typedproperty import typedproperty
175181

176-
class Stock(object):
182+
class Stock:
177183
name = typedproperty('name', str)
178184
shares = typedproperty('shares', int)
179185
price = typedproperty('price', float)
@@ -211,7 +217,7 @@ Float = lambda name: typedproperty(name, float)
211217
Now, rewrite the `Stock` class to use these functions instead:
212218

213219
```python
214-
class Stock(object):
220+
class Stock:
215221
name = String('name')
216222
shares = Integer('shares')
217223
price = Float('price')

Notes/07_Advanced_Topics/04_Function_decorators.md

+15-7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
[Contents](../Contents) \| [Previous (7.3 Returning Functions)](03_Returning_functions) \| [Next (7.5 Decorated Methods)](05_Decorated_methods)
2+
13
# 7.4 Function Decorators
24

35
This section introduces the concept of a decorator. This is an advanced
@@ -12,7 +14,7 @@ def add(x, y):
1214
return x + y
1315
```
1416

15-
Now, consider the function with some logging.
17+
Now, consider the function with some logging added to it.
1618

1719
```python
1820
def add(x, y):
@@ -32,13 +34,15 @@ def sub(x, y):
3234

3335
*Observation: It's kind of repetitive.*
3436

35-
Writing programs where there is a lot of code replication is often really annoying.
36-
They are tedious to write and hard to maintain.
37-
Especially if you decide that you want to change how it works (i.e., a different kind of logging perhaps).
37+
Writing programs where there is a lot of code replication is often
38+
really annoying. They are tedious to write and hard to maintain.
39+
Especially if you decide that you want to change how it works (i.e., a
40+
different kind of logging perhaps).
3841

39-
### Example continuation
42+
### Code that makes logging
4043

41-
Perhaps you can make *logging wrappers*.
44+
Perhaps you can make a function that makes functions with logging
45+
added to them. A wrapper.
4246

4347
```python
4448
def logged(func):
@@ -65,7 +69,9 @@ logged_add(3, 4) # You see the logging message appear
6569

6670
This example illustrates the process of creating a so-called *wrapper function*.
6771

68-
**A wrapper is a function that wraps another function with some extra bits of processing.**
72+
A wrapper is a function that wraps around another function with some
73+
extra bits of processing, but otherwise works in the exact same way
74+
as the original function.
6975

7076
```python
7177
>>> logged_add(3, 4)
@@ -100,6 +106,8 @@ It is said to *decorate* the function.
100106
There are many more subtle details to decorators than what has been presented here.
101107
For example, using them in classes. Or using multiple decorators with a function.
102108
However, the previous example is a good illustration of how their use tends to arise.
109+
Usually, it's in response to repetitive code appearing across a wide range of
110+
function definitions. A decorator can move that code to a central definition.
103111

104112
## Exercises
105113

0 commit comments

Comments
 (0)