Thursday, July 12, 2018

Python Crib Sheet #2


Context managers - aka 'with'

"Context managers wrap a block and manage requirements on entry and departure from the block and are marked by the with keyword. File objects are context managers... we know that the file will be closed immediately after the last read, whether the operation was successful or not... closure of the file is also assured, because it’s part of the file object’s context management, so we don’t need to write the code. In other words, by using with combined with a context management (in this case a file object), we don’t need to worry about the routine cleanup." [1]

In pseudo-code (from effbot):

    class controlled_execution:
        def __enter__(self):
            set things up
            return thing
        def __exit__(self, type, value, traceback):
            tear things down

    with controlled_execution() as thing:
         some code


* Operator

"A special parameter can be defined that will collect all extra positional arguments in a function call into a tuple" [1]. See the example here where "zip is its own inverse". That is, it can both turn two lists into one list of tuples (as you'd expect) and also turn a list of tuples into two lists.

For example:

>>> def g(*x):
...     for a in x:
...         print(a)
... 
>>> g(*(1, 2))
1
2
>>> g((1, 2))
(1, 2)
>>> g(*[(1, 2), (3, 4)])
(1, 2)
(3, 4)
>>> g([(1, 2), (3, 4)])

[(1, 2), (3, 4)]

That is, adding * means the tuple or list becomes a sequence of their constituents.

To summarize:

def g(*x)def g(x)
g((1, 2))[(1,2)][1, 2]
g(*(1, 2))[1, 2]TypeError


The future works (certain T&Cs may apply)

"It’s possible to import several features of Python 3, like division, into Python 2.x by using the __future__ module; but even if you imported all the features of the __future__ library, the differences in library structure, the distinction between strings and Unicode, and so on all would make for code that would be hard to maintain and debug." [1]

"With __future__ module's inclusion, you can slowly be accustomed to incompatible changes or to such ones introducing new keywords." (StackOverflow).

An example is the differences between integer division in Python 2 and 3. In Python 2, the result is another integer, in Python 3 it's a float. Using __future__ can make Python 2 work like Python 3:

$ python
Python 2.7.12 (default, Nov 19 2016, 06:48:10)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 1/3
0
>>> from __future__ import division
>>> 1/3
0.3333333333333333

[1] The Quick Python Book

No comments:

Post a Comment