Contents
1 Lambda Expressions
Small anonymous functions can be created with the lambda
keyword. This function returns the sum of its two arguments: lambda a, b: a+b
. Lambda functions can be used wherever function objects are required. They are syntactically restricted to a single expression. Semantically, they are just syntactic sugar for a normal function definition. Like nested function definitions, lambda functions can reference variables from the containing scope:
>>> def make_incrementor(n):
... return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43
The above example uses a lambda expression to return a function. Another use is to pass a small function as an argument:
>>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
>>> pairs.sort(key=lambda pair: pair[1])
>>> pairs
[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
2 Decorators
Add functionality to an existing function with decorators. This is called metaprogramming.
A function can take a function as argument (the function to be decorated) and return the same function with or without extension.
2.1 Functions are objects
def hello():
print("Hello")
# even functions are objects
message = hello
# call new function
message()
Call the methods either message()
or hello()
and they have the same output. That’s because they refer to the same object.
2.2 Decorators
A decorator takes a function, extends it and returns. Yes, a function can return a function.
def hello(func):
def inner():
print("Hello ")
func()
return inner
def name():
print("Alice")
obj = hello(name)
obj()
①In the above example, hello()
is a decorator.
In the statement
obj = hello(name)
the function name()
is decorated by the function hello()
.
It wraps the function in the other function.
②Functions can be extended by wrapping them.
def who():
print("Alice")
def display(func):
def inner():
print("The current user is : ", end="")
func()
return inner
if __name__ == "__main__":
myobj = display(who)
myobj()
The function who()
gets decorated by display()
.
2.3 Syntactic sugar
Decorators are common and can be simplified. While it does exactly the same, its just cleaner code.
Python can simplify the use of decorators with the @ symbol.
@hello
def name():
print("Alice")
if __name__ == "__main__":
name()
This will output exactly the same, but is a cleaner way to write the code.
Stay with me. The call
@hello
def name():
is just a simpler way of writing:
obj = hello(name)
In both cases we apply the decorator to a function.
2.4 Arguments
Parameters can be used with decorators. If you have a funtion that prints the sum a + b, like this
def sumab(a,b):
summed = a + b
print(summed)
You can wrap it in a decorator function.
The example below shows how to do that:
def pretty_sumab(func):
def inner(a,b):
print(str(a) + " + " + str(b) + " is ", end="")
return func(a,b)
return inner
@pretty_sumab
def sumab(a,b):
summed = a + b
print(summed)
if __name__ == "__main__":
sumab(5,3)
The function sumab
is wrapped by the function pretty_sumab
. This is indicated with the @ symbol above it.
Call the function sumab
, and see that both the logic of the functions sumab and pretty_sumab
are run, with parameters.
3 PEP 8
For Python, PEP 8 has emerged as the style guide that most projects adhere to; it promotes a very readable and eye-pleasing coding style. Every Python developer should read it at some point; here are the most important points extracted for you:
-
Use 4-space indentation, and no tabs.
4 spaces are a good compromise between small indentation (allows greater nesting depth) and large indentation (easier to read). Tabs introduce confusion, and are best left out. -
Wrap lines so that they don’t exceed 79 characters.
This helps users with small displays and makes it possible to have several code files side-by-side on larger displays. -
Use blank lines to separate functions and classes, and larger blocks of code inside functions.
-
When possible, put comments on a line of their own.
-
Use docstrings.
-
Use spaces around operators and after commas, but not directly inside bracketing constructs:
a = f(1, 2) + g(3, 4)
. -
Name your classes and functions consistently; the convention is to use
UpperCamelCase
for classes andlowercase_with_underscores
for functions and methods. Always useself
as the name for the first method argument (see A First Look at Classes for more on classes and methods). -
Don’t use fancy encodings if your code is meant to be used in international environments. Python’s default, UTF-8, or even plain ASCII work best in any case.
-
Likewise, don’t use non-ASCII characters in identifiers if there is only the slightest chance people speaking a different language will read or maintain the code.
4 Exercise
Q: Please use a decorator to find the time it takes for an existing function to execute.
- You can use
time
module to complete this topic.
import time
def run_time(func):
def inner():
a = time.time()
func()
b = time.time() - a
print('The function execution time is %ss.'%(b))
return inner
@run_time
def test():
for i in range(3):
time.sleep(1)
test()