@classmethod
decorator. Then this method can be called directly from the class, not from its instances, and it will take the class as the first argument (it is usually called cls
, not self
).__new__
and __init_subclass__
. They work as if they were also decorated with @classmethod
, although this is not the case ( __new__
creates new instances of the class, and __init_subclass__
is a hook that is called when creating a derived class). class Foo: def __new__(cls, *args, **kwargs): print(cls) return super().__new__( cls, *args, **kwargs ) Foo() # <class '__main__.Foo'>
m.__enter__()
and m.__exit__()
Python will do await on m.__aenter__()
and m.__aexit__()
respectively.async with
: import asyncio class Slow: def __init__(self, delay): self._delay = delay async def __aenter__(self): await asyncio.sleep(self._delay / 2) async def __aexit__(self, *exception): await asyncio.sleep(self._delay / 2) async def main(): async with Slow(1): print('slow') loop = asyncio.get_event_loop() loop.run_until_complete(main())
contextlib
provides the contextlib
decorator, which allows you to define an asynchronous context manager in the same way that the contextmanager
does: import asyncio from contextlib import asynccontextmanager @asynccontextmanager async def slow(delay): half = delay / 2 await asyncio.sleep(half) yield await asyncio.sleep(half) async def main(): async with slow(1): print('slow') loop = asyncio.get_event_loop() loop.run_until_complete(main())
@asyncio_extras.async_contextmanager
.++
operator, x += 1
used instead. But at the same time, the syntax ++x
is valid (and x++
is no longer).++x
is actually x.__pos__().__pos__()
. This can be abused and make ++
work as an increment (but I would not recommend it): class Number: def __init__(self, value): self._value = value def __pos__(self): return self._Incrementer(self) def inc(self): self._value += 1 def __str__(self): return str(self._value) class _Incrementer: def __init__(self, number): self._number = number def __pos__(self): self._number.inc() x = Number(4) print(x) # 4 ++x print(x) # 5
MagicMock
object allows MagicMock
to take in any attribute and call any method. With this access method, a new stub (mock) is returned. Moreover, you get the same stub object if you access the same attribute (or call the same method): >>> from unittest.mock import MagicMock >>> m = MagicMock() >>> a = ma >>> b = mb >>> a is ma True >>> mx() is mx() True >>> mx() <MagicMock name='mock.x()' id='139769776427752'>
>>> mabcd <MagicMock name='mock.abcd' id='139769776473480'> >>> mabcd <MagicMock name='mock.abcd' id='139769776473480'> >>> mx().y().z() <MagicMock name='mock.x().y().z()' id='139769776450024'> >>> mx(1).y(1).z(1) <MagicMock name='mock.x().y().z()' id='139769776450024'>
>>> mabcd = 42 >>> mabcd 42 >>> mxreturn_value.y.return_value = 13 >>> mx().y() 13
m[1][2]
. The fact is that MagicMock
does not handle the call to the element, it is just a method call: >>> m[1][2] = 3 >>> m[1][2] <MagicMock name='mock.__getitem__().__getitem__()' id='139769776049848'> >>> m.__getitem__.return_value.__getitem__.return_value = 50 >>> m[1][2] 50
Source: https://habr.com/ru/post/438778/