More on this book
Community
Kindle Notes & Highlights
Started reading
February 23, 2019
For example, the syntax obj[key] is supported by the __getitem__ special method.
If a collection has no __contains__ method, the in operator does a sequential scan.
special methods is that they are meant to be called by the Python interpreter, and not by
__repr__ should be unambiguous and, if possible, match the source code necessary to re-create the object being represented.
Contrast __repr__ with __str__, which is called by the str() constructor and implicitly used by the print function. __str__ should return a string suitable for display to end users.
By default, instances of user-defined classes are considered truthy, unless either __bool__ or __len__ is implemented.
Container sequences hold references to the objects they contain, which may be of any type, while flat sequences physically store the value of each item within its own memory space, and not as distinct objects. Thus, flat sequences are more compact, but they are limited to holding primitive values like characters, bytes, and numbers.
In Python code, line breaks are ignored inside pairs of [], {}, or (). So you can build multiline lists, listcomps, genexps, dictionaries and the like without using the ugly \ line continuation escape.
Listcomps can generate lists from the Cartesian product of two or more iterables.
list is arranged as if the for loops were nested in the same order as they appear in the listcomp.
To initialize tuples, arrays, and other types of sequences, you could also start from a listcomp, but a genexp saves memory because it yields items one by one using the iterator protocol instead of building a whole list just to feed another constructor.
“unpacking.” Here we are not interested in the second item, so it’s assigned to _, a dummy variable.
The preceding code also shows a further use of tuple unpacking: enabling functions to return multiple values in a way that is convenient to the caller.
In Python 3, this idea was extended to apply to parallel assignment as well:
The collections.namedtuple function is a factory that produces subclasses of tuple enhanced with field names and a class name — which helps debugging.
be passed as positional arguments to the constructor (in contrast, the tuple constructor takes a single iterable).
Instead of filling your code with hardcoded slices, you can name them. See how readable this makes the for loop at the end of the example.
... 0.....6.................................40........52...55........
34.95 1 $34.95 ... """ >>> SKU = slice(0, 6)
In other words, to evaluate a[i, j], Python calls a.__getitem__((i, j)).
NumPy uses ... as a shortcut when slicing arrays of many dimensions; for example, if x is a four-dimensional array, x[i, ...] is a shortcut for x[i, :, :, :,].
Mutable sequences can be grafted, excised, and otherwise modified in place using slice notation on the left side of an assignment statement or as the target of a del statement.
When the target of the assignment is a slice, the right side must be an iterable object, even if it has just one item.
To concatenate multiple copies of the same sequence, multiply it by an integer.
This is an important Python API convention: functions or methods that change an object in place should return None to make it clear to the caller that the object itself was changed, and no new object was created.
Because the sorting algorithm is stable, “grape” and “apple,” both of length 5, are in the original order.
The append and popleft operations are atomic, so deque is safe to use as a FIFO queue in multithreaded applications without the need for using locks.
A defaultdict is configured to create items on demand whenever a missing key is searched.
infix operators, so, given two sets a and b, a | b returns their union, a & b computes the intersection, and a - b the difference.
The hash() built-in function works directly with built-in types and falls back to calling __hash__ for user-defined types.
Figure 3-3
For user-defined types, the __slots__ class attribute changes the storage of instance attributes from a dict to a tuple in each instance. This will be discussed in “Saving Space with the __slots__ Class Attribute” (Chapter 9).
Optimization is the altar where maintainability is sacrificed.
If a class defines a __call__ method, then its instances may be invoked as functions.
building a local copy prevents unexpected side effects on any list passed as an argument.
The message from Peter Norvig’s design patterns slides is that the Command and Strategy patterns — along with Template Method and Visitor — can be made simpler or even “invisible” with first-class functions, at least for some applications of these patterns.
Expert Python Programming
The second crucial fact is that they are executed immediately when a module is loaded.
Note that register runs (twice) before any other function in the module.
The main point of Example 7-2 is to emphasize that function decorators are executed as soon as the module is imported, but the decorated functions only run when they are explicitly invoked.
If we want the interpreter to treat b as a global variable in spite of the assignment within the function, we use the global declaration:
a closure is a function with an extended scope that encompasses nonglobal variables referenced in the body of the function but not defined there.
Python has three built-in functions that are designed to decorate methods: property, classmethod, and staticmethod.
because lru_cache uses a dict to store the results, and the keys are made from the positional and keyword arguments used in the calls, all the arguments taken by the decorated function must be hashable.
We also visited two awesome function decorators provided in the functools module of standard library: @lru_cache() and @singledispatch
The theme is the distinction between objects and their names. A name is not the object; a name is a separate thing.
A surprising trait of tuples is revealed: they are immutable but their values may change.
Python variables are like reference variables in Java, so it’s better to think of them as labels attached to objects.
To understand an assignment in Python, always read the right-hand side first: that’s where the object is created or retrieved.
An object’s identity never changes once it has been created; you may think of it as the object’s address in memory. The is operator compares the identity of two objects; the id() function returns an integer representing its identity.