- PVSM.RU - https://www.pvsm.ru -
Это седьмая подборка советов про Python и программирование из моего авторского канала @pythonetc.
Предыдущие подборки:
Иногда бывает нужно запустить какой-то блок кода в нескольких менеджерах контекста:
with open('f') as f:
with open('g') as g:
with open('h') as h:
pass
Со времён Python 2.7 и 3.1 это можно сделать с помощью одного выражения:
o = open
with o('f') as f, o('g') as g, o('h') as h:
pass
А раньше можно было воспользоваться функцией contextlib.nested
:
with nested(o('f'), o('g'), o('h')) as (f, g, h):
pass
Если вы работаете с неопределённым количеством менеджеров контекста, то лучше выбрать более продвинутые инструменты. contextlib.ExitStack
позволяет в любое время входить в любое количество контекстов и гарантирует выход из них по окончании исполнения:
with ExitStack() as stack:
f = stack.enter_context(o('f'))
g = stack.enter_context(o('g'))
other = [
stack.enter_context(o(filename))
for filename in filenames
]
Ко всем объектам, которые в данный момент находятся в памяти интерпретатора, можно получить доступ с помощью 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)]
In : int('୧৬༣')
Out: 163
0 1 2 3 4 5 6 7 8 9
— это не единственные символы, считающиеся цифрами. Python соблюдает правила Unicode и считает цифрами несколько сотен символов. Полный список здесь [7].
Это имеет значение для функций вроде int
, unicode.isdecimal
и даже re.match
:
In : int('௯')
Out: 9
In : '٢'.isdecimal()
Out: True
In : bool(re.match('d', '౫'))
Out: True
>>> bool(datetime(2018, 1, 1).time())
False
>>> bool(datetime(2018, 1, 1, 13, 12, 11).time())
True
До Pyhon 3.5 объекты datetime.time()
считались ложными, если они представляли полночь по UTC. Это может приводить к неочевидным багам. В следующем примере if not
может не выполниться не потому, что create_time
является None
, а потому что это полночь.
def create(created_time=None) -> None:
if not created_time:
created_time = datetime.now().time()
Обойти этот баг можно с помощью явной проверки на None
: if created_time is None
.
Python не поддерживает асинхронные операции с файлами. Чтобы сделать их неблокирующими, приходится использовать треды.
Для асинхронного исполнения кода в потоке нужно использовать метод loop.run_in_executor
.
За вас это может сделать сторонний модуль aiofiles
, предоставляющий удобный и простой интерфейс:
async with aiofiles.open('filename', mode='r') as f:
contents = await f.read()
Автор: Пуштаев Вадим
Источник [8]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/python/305540
Ссылки в тексте:
[1] Ноябрь 2018: https://habr.com/ru/company/mailru/blog/432628/
[2] Октябрь 2018: https://habr.com/company/mailru/blog/429186/
[3] Сентябрь 2018: https://habr.com/company/mailru/blog/425125/
[4] Август 2018: https://habr.com/company/mailru/blog/422789/
[5] Июль 2018: https://habr.com/company/mailru/blog/419025/
[6] Июнь 2018: https://habr.com/company/mailru/blog/416605/
[7] здесь: http://www.fileformat.info/info/unicode/category/Nd/list.htm
[8] Источник: https://habr.com/ru/post/436322/?utm_source=habrahabr&utm_medium=rss&utm_campaign=436322
Нажмите здесь для печати.