Study notes of fluent Python -- first class functions

Notes on fluent Python (6) - first class functions

In Python, everything is an object, which can explain some strange problems in Python.

1. Python function is an object

In Python, a function is a first-class object, satisfying four conditions:

  1. Create at run time
  2. Can be assigned to an element in a variable or data structure
  3. Can be passed to a function as a parameter
  4. Can be the return result of a function

Among them, 1, 2, 3 and 4 points can be reflected in the decorator, which will be elaborated in the second part. An example is given to illustrate these four features.

>>> fact = factorial
>>> fact
<function factorial at 0x...>
>>> fact(5)
>>> map(factorial, range(11))
<map object at 0x...>
>>> list(map(fact, range(11)))
[1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]

Then as an object, it must have its properties and methods (also objects), as well as functional programming. Next, it analyzes and studies the properties and methods of function objects, as well as higher-order functions.

1.1 properties and methods of function objects

Using the dir function in Python, you can see all the properties and methods of an object.
Define the object Hello:

def Hello():

View its properties and methods:

In [14]: dir(hello)
['__annotations__', '__call__', '__class__', '__closure__', '__code__', 
'__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', 
'__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', 
'__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', 
'__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', 
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', 
'__str__', '__subclasshook__']

Compared with ordinary objects, function objects have more attributes and methods:

Among them, several notable features are: "call", "close", "anonications". As long as you implement the call method, you can make any Python object behave like a function.

Anonymous function and higher order function

2.1 anonymous functions

Lambda function can only use the function of pure expression, and it can't be assigned, whlie, try and other statements in lambda function.
The definition of lambda function is

lambda args: expression

Equivalent to

def func(args):
    return expression

An example of an anonymous function sorting a string with an ending letter is:

fruits = ['strawberry', 'fig', 'apple', 'cherry', 'raspberry', 'banana']
sorted(fruits, key=lambda word: word[::-1])

Here, the lambda function takes word as a parameter and outputs word in reverse order.

2.2 advanced features map, filter and reduce

These advanced features have been largely replaced by list derivation and generator expressions.

  • The main function of the map function is to act on each element of the object that can be iterated. The function is similar to
data = [1,2,3]
map(func, data) # ⇒ [func(1), func(2), func(3)]
[func(i) for i in data]
  • The filter function mainly controls which elements should be used, which is equivalent to the if statement of list derivation
  • reduce is to accumulate the iteratable objects

2.3 function annotation

Deep learning model programming is commonly used to mark the type of data

def clip(text:str, max_len:'int > 0'=80) -> str: #➊
	"""stay max_len Truncate text at first space before or after
	end = None
	if len(text) > max_len:
		space_before = text.rfind(' ', 0, max_len)
	if space_before >= 0:
		end = space_before
		space_after = text.rfind(' ', max_len)
	if space_after >= 0:
		end = space_after
	if end is None: # No spaces found
		end = len(text)
	return text[:end].rstrip()

In neural networks, we can often see similar definitions, such as the forward function of the following column, because different data have different mathematical processing methods. At this time, if we use the polymorphism feature in object-oriented programming on a large scale, it will be difficult to debug the model:

class NMT(nn.Module):
    """ Simple Neural Machine Translation Model:
        - Transformer Encoder
        - Transformer Decoder
        - Self-Attention --ref:Attention is all you need
    def __init__(self, d_model, vocab, num_layer=6, num_heads=8, dropout_rate=0.2):

    def forward(self, source: List[List[str]], target: List[list[str]]) -> torch.Tensor:

Function annotation basically has no function in the interpreter. It just stores the annotation in the "annotations" attribute to prompt the programmer to pay attention to the parameter type. In addition, it can also be used for parameter type test. For specific methods, please refer to

Stack Overflow Problems in the website“ What are good uses for Python3's' Function Annotations'"(, Raymond Hettinger gives practical answers and in-depth insights;

Application 2: parameter test

def validate(func, locals):
    for var, test in func.__annotations__.items():
        value = locals[var]
        msg = 'Var: {0}\tValue: {1}\tTest: {2.__name__}'.format(var, value, test)
        assert test(value), msg

def is_int(x):
    return isinstance(x, int)

def between(lo, hi):
    def _between(x):
            return lo <= x <= hi
    return _between

def f(x: between(3, 10), y: is_int):
    validate(f, locals())
    print(x, y)

# test result
>>> f(0, 31.1)
Traceback (most recent call last):
AssertionError: Var: y  Value: 31.1 Test: is_int

2.4 key only

The so-called keyword only parameter is that parameter can only be passed by the way of "parameter name = actual parameter". It is generally used for parameters that are important to function characteristics. The definition form is:

def func(a, * ,b):
    return a, b
func(1, b=1) # right
func(1, 1)   # wrong

Keyword only is a new feature in Python 3, which must be after an indefinite number of location parameters or a separate * value.

Published 5 original articles, won praise 2, visited 355
Private letter follow

Tags: Python Lambda Programming Attribute

Posted on Tue, 04 Feb 2020 03:17:38 -0500 by kroll