Compilation @pythonetc, December 2018

    This is the seventh collection of tips about Python and programming from my author’s @pythonetc channel.

    Previous selections:

    Multiple contexts

    Sometimes you need to run some block of code in several context managers:

    with open('f') as f:
        with open('g') as g:
            with open('h') as h:

    Since the days of Python 2.7 and 3.1, this can be done with a single expression:

    o = open
    with o('f') as f, o('g') as g, o('h') as h:

    And before that you could use the function contextlib.nested:

    with nested(o('f'), o('g'), o('h')) as (f, g, h):

    If you are working with an unspecified number of context managers, it is better to choose more advanced tools. contextlib.ExitStackallows to enter any number of contexts at any time and guarantees exit from them at the end of execution:

    with ExitStack() as stack:
        f = stack.enter_context(o('f'))
        g = stack.enter_context(o('g'))
        other = [
            for filename in filenames

    Objects in interpreter memory

    All objects that are currently in the memory of the interpreter can be accessed using gc.get_objects():

    In : classA:
    ...:     def__init__(self, x):
    ...:         self._x = x
    ...:     def__repr__(self):
    ...:         class_name = type(self).__name__
    ...:         x = self._x
    ...:         returnf'{class_name}({x!r})'
    In : A(1)
    Out: A(1)
    In : A(2)
    Out: A(2)
    In : A(3)
    Out: A(3)
    In : [x for x in gc.get_objects() if isinstance(x, A)]
    Out: [A(1), A(2), A(3)]

    Character Numbers

    In : int('୧৬༣')
    Out: 163

    0 1 2 3 4 5 6 7 8 9- These are not the only characters that are considered numbers. Python follows the rules of Unicode and counts numbers as hundreds of characters. Full list here .

    It matters for functions like int, unicode.isdecimaland even re.match:

    In : int('௯')
    Out: 9
    In : '٢'.isdecimal()
    Out: True
    In : bool(re.match('\d', '౫'))
    Out: True

    Midnight UTC

    >>> bool(datetime(2018, 1, 1).time())
    False>>> bool(datetime(2018, 1, 1, 13, 12, 11).time())

    Before Pyhon 3.5, objects datetime.time()were considered false if they represented midnight UTC. This can lead to unobvious bugs. In the following example, it if notmay not be executed, not because it create_time
    is None, but because it is midnight.

    defcreate(created_time=None) -> None:ifnot created_time:
            created_time =

    Around this bug, you can use explicit checks on None: if created_time is None.

    Asynchronous work in FS

    Python does not support asynchronous file operations. To make them non-blocking, you have to use threads.

    For asynchronous code execution in a stream, you need to use the method loop.run_in_executor.

    For you this can be done by a third-party module aiofilesthat provides a convenient and simple interface:

    asyncwith'filename', mode='r') as f:
        contents = await

    Also popular now: