
这是我的@pythonetc feed中的第七种Python技巧和编程。
先前的选择:
多种环境
有时可能需要在多个上下文管理器中运行代码块:
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规则,并将数百个字符视为数字。 完整列表
在这里 。
这对于
int
,
unicode.isdecimal
甚至
re.match
类的函数
unicode.isdecimal
re.match
:
In : int('௯') Out: 9 In : '٢'.isdecimal() Out: True In : bool(re.match('\d', '౫')) Out: True
UTC午夜
>>> bool(datetime(2018, 1, 1).time()) False >>> bool(datetime(2018, 1, 1, 13, 12, 11).time()) True
在Pyhon 3.5之前的版本中,如果
datetime.time()
对象表示午夜UTC,则将它们视为false。 这可能导致不明显的错误。 在以下示例中,
if not
,
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
来解决此错误。
FS中的异步工作
Python不支持异步文件操作。 为了使它们无阻塞,您必须使用线程。
为了在流中执行异步代码,您需要使用
loop.run_in_executor
方法。
第三方
aiofiles
模块可以为您做到这一点,提供了一个方便而简单的界面:
async with aiofiles.open('filename', mode='r') as f: contents = await f.read()