Как стать автором
Технологии, которые объединяют

Tips and tricks from my Telegram-channel @pythonetc, December 2018

Блог компании VK Python *Программирование *

It is new selection of tips and tricks about Python and programming from my Telegram-channel @pythonetc.

Multiple context managers

Sometimes you want to run a code block with multiple context managers:

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

Since Python 2.7 and 3.1, you can do it with a single with expression:

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

Before that, you could you use the contextlib.nested function:

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

If you are working with the unknown number of context manager, the more advanced tool suits you well. contextlib.ExitStack allows you to enter any number of contexts at the arbitrary time but guarantees to exit them at the end:

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

Objects in the interpreter memory

All objects that currently exist in the interpreter memory can be accessed via gc.get_objects():

In : class A:
...:     def __init__(self, x):
...:         self._x = x
...:     def __repr__(self):
...:         class_name = type(self).__name__
...:         x = self._x
...:         return f'{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)]

Digit symbols

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

0 1 2 3 4 5 6 7 8 9 — are not the only characters that are considered digits. Python follows Unicode rules and treats several hundreds of symbols as digits, here is the full list (http://www.fileformat.info/info/unicode/category/Nd/list.htm).

That affects functions like int, unicode.isdecimal and even re.match:

In : int('෯')
Out: 9

In : '٢'.isdecimal()
Out: True

In : bool(re.match('\d', '౫'))
Out: True

UTC midnight

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

Before Python 3.5, datetime.time() objects were considered false if they represented UTC midnight. That can lead to obscure bugs. In the following examples if not may run not because create_time is None, but because it's a midnight.

def create(created_time=None) -> None:
    if not created_time:
        created_time = datetime.now().time()

You can fix that by explicitly testing for None: if created_time is None.

Asynchronous file operations

There is no support in Python for asynchronous file operations. To make them non-blocking, you have to use separate threads.

To asynchronously run code in the thread, you should use the loop.run_in_executor method.

The third party aiofiles module does all this for you providing nice and simple interface:

async with aiofiles.open('filename', mode='r') as f:
    contents = await f.read()

Source: habr.com/ru/company/mailru/blog/436322
Всего голосов 31: ↑31 и ↓0 +31
Просмотры 1.8K
Комментарии Комментарии 1


Дата основания
5 001–10 000 человек
Дата регистрации
Миша Буданов