Python Pass Keywords Notes
Python Pass Keywords Notes
>>>
...
>>>
... pass
...
Another place pass can be used is as a place-holder for a function or conditional body when you are
working on new code, allowing you to keep thinking at a more abstract level. The pass is silently
ignored:
>>>
...
A match statement takes an expression and compares its value to successive patterns given as one
or more case blocks. This is superficially similar to a switch statement in C, Java or JavaScript (and
many other languages), but it can also extract components (sequence elements or object attributes)
from the value into variables.
The simplest form compares a subject value against one or more literals:
def http_error(status):
match status:
case 400:
case 418:
case _:
Note the last block: the “variable name” _ acts as a wildcard and never fails to match. If no case
matches, none of the branches is executed.
Patterns can look like unpacking assignments, and can be used to bind variables:
match point:
print("Origin")
print(f"Y={y}")
print(f"X={x}")
print(f"X={x}, Y={y}")
case _:
Study that one carefully! The first pattern has two literals, and can be thought of as an extension of
the literal pattern shown above. But the next two patterns combine a literal and a variable, and the
variable binds a value from the subject (point). The fourth pattern captures two values, which makes
it conceptually similar to the unpacking assignment (x, y) = point.
If you are using classes to structure your data you can use the class name followed by an argument
list resembling a constructor, but with the ability to capture attributes into variables:
class Point:
x: int
y: int
def where_is(point):
match point:
print("Origin")
print(f"Y={y}")
print(f"X={x}")
case Point():
print("Somewhere else")
case _:
print("Not a point")
You can use positional parameters with some builtin classes that provide an ordering for their
attributes (e.g. dataclasses). You can also define a specific position for attributes in patterns by
setting the __match_args__ special attribute in your classes. If it’s set to (“x”, “y”), the following
patterns are all equivalent (and all bind the y attribute to the var variable):
Point(1, var)
Point(1, y=var)
Point(x=1, y=var)
Point(y=var, x=1)
A recommended way to read patterns is to look at them as an extended form of what you would put
on the left of an assignment, to understand which variables would be set to what. Only the
standalone names (like var above) are assigned to by a match statement. Dotted names (like
foo.bar), attribute names (the x= and y= above) or class names (recognized by the “(…)” next to them
like Point above) are never assigned to.
Patterns can be arbitrarily nested. For example, if we have a short list of points, we could match it
like this:
match points:
case []:
print("No points")
print("The origin")
case _:
print("Something else")
We can add an if clause to a pattern, known as a “guard”. If the guard is false, match goes on to try
the next case block. Note that value capture happens before the guard is evaluated:
match point:
case Point(x, y) if x == y:
print(f"Y=X at {x}")
Like unpacking assignments, tuple and list patterns have exactly the same meaning and actually
match arbitrary sequences. An important exception is that they don’t match iterators or strings.
Sequence patterns support extended unpacking: [x, y, *rest] and (x, y, *rest) work similar to
unpacking assignments. The name after * may also be _, so (x, y, *_) matches a sequence of at least
two items without binding the remaining items.
Mapping patterns: {"bandwidth": b, "latency": l} captures the "bandwidth" and "latency" values from
a dictionary. Unlike sequence patterns, extra keys are ignored. An unpacking like **rest is also
supported. (But **_ would be redundant, so it not allowed.)
will capture the second element of the input as p2 (as long as the input is a sequence of two points)
Most literals are compared by equality, however the singletons True, False and None are compared
by identity.
Patterns may use named constants. These must be dotted names to prevent them from being
interpreted as capture variable:
class Color(Enum):
RED = 0
GREEN = 1
BLUE = 2
match color:
case Color.RED:
case Color.GREEN:
print("Grass is green")
case Color.BLUE:
For a more detailed explanation and additional examples, you can look into PEP 636 which is written
in a tutorial format.
We can create a function that writes the Fibonacci series to an arbitrary boundary:
>>>
... a, b = 0, 1
... a, b = b, a+b
... print()
...
... fib(2000)
The keyword def introduces a function definition. It must be followed by the function name and the
parenthesized list of formal parameters. The statements that form the body of the function start at
the next line, and must be indented.
The first statement of the function body can optionally be a string literal; this string literal is the
function’s documentation string, or docstring. (More about docstrings can be found in the section
Documentation Strings.) There are tools which use docstrings to automatically produce online or
printed documentation, or to let the user interactively browse through code; it’s good practice to
include docstrings in code that you write, so make a habit of it.
The execution of a function introduces a new symbol table used for the local variables of the
function. More precisely, all variable assignments in a function store the value in the local symbol
table; whereas variable references first look in the local symbol table, then in the local symbol tables
of enclosing functions, then in the global symbol table, and finally in the table of built-in names.
Thus, global variables and variables of enclosing functions cannot be directly assigned a value within
a function (unless, for global variables, named in a global statement, or, for variables of enclosing
functions, named in a nonlocal statement), although they may be referenced.
The actual parameters (arguments) to a function call are introduced in the local symbol table of the
called function when it is called; thus, arguments are passed using call by value (where the value is
always an object reference, not the value of the object). 1 When a function calls another function, or
calls itself recursively, a new local symbol table is created for that call.
A function definition associates the function name with the function object in the current symbol
table. The interpreter recognizes the object pointed to by that name as a user-defined function.
Other names can also point to that same function object and can also be used to access the function:
>>>
>>> fib
>>> f = fib
>>> f(100)
0 1 1 2 3 5 8 13 21 34 55 89
Coming from other languages, you might object that fib is not a function but a procedure since it
doesn’t return a value. In fact, even functions without a return statement do return a value, albeit a
rather boring one. This value is called None (it’s a built-in name). Writing the value None is normally
suppressed by the interpreter if it would be the only value written. You can see it if you really want
to using print():
>>>
>>> fib(0)
>>> print(fib(0))
None
It is simple to write a function that returns a list of the numbers of the Fibonacci series, instead of
printing it:
>>>
... result = []
... a, b = 0, 1
... a, b = b, a+b
...
>>> f100 = fib2(100) # call it
The return statement returns with a value from a function. return without an expression argument
returns None. Falling off the end of a function also returns None.
The statement result.append(a) calls a method of the list object result. A method is a function that
‘belongs’ to an object and is named obj.methodname, where obj is some object (this may be an
expression), and methodname is the name of a method that is defined by the object’s type. Different
types define different methods. Methods of different types may have the same name without
causing ambiguity. (It is possible to define your own object types and methods, using classes, see
Classes) The method append() shown in the example is defined for list objects; it adds a new
element at the end of the list. In this example it is equivalent to result = result + [a], but more
efficient.