
рдпрд╣ рдореЗрд░реЗ рдЯреЗрд▓реАрдЧреНрд░рд╛рдо-рдЪреИрдирд▓ @pythonetc рд╕реЗ рдкрд╛рдпрдерди рдФрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЯрд┐рдкреНрд╕ рдФрд░ рдЯреНрд░рд┐рдХреНрд╕ рдХрд╛ рдирдпрд╛ рдЪрдпрди рд╣реИред
рдкрд┐рдЫрд▓реЗ рдкреНрд░рдХрд╛рд╢рди:
рджреЛ рдирд┐рд╣рд┐рдд рд╡рд░реНрдЧ рд╡рд┐рдзрд┐рдпрд╛рдБ
рдХреНрд▓рд╛рд╕ рд╡рд┐рдзрд┐ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ
@classmethod
рдбреЗрдХреЛрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕ рд╡рд┐рдзрд┐ рдХреЛ рдХрдХреНрд╖рд╛ рд╕реЗ рд╕реАрдзреЗ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рди рдХрд┐ рдЗрд╕рдХреЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рд╕реЗ, рдФрд░ рдХрдХреНрд╖рд╛ рдХреЛ рдкрд╣рд▓реЗ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ (рдЖрдорддреМрд░ рдкрд░ рдЗрд╕реЗ
cls
рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ,
self
рдирд╣реАрдВ)ред
рд╣рд╛рд▓рд╛рдБрдХрд┐, рдкрд╛рдпрдерди рдбреЗрдЯрд╛ рдореЙрдбрд▓ рдореЗрдВ рджреЛ рдирд┐рд╣рд┐рдд рд╡рд░реНрдЧ рд╡рд┐рдзрд┐рдпрд╛рдБ рд╣реИрдВ:
__new__
рдФрд░
__init_subclass__
ред рд╡реЗ рдареАрдХ рд╡реИрд╕реЗ рд╣реА рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ рдЬреИрд╕реЗ рд╡реЗ
@classmethod
рд╕рд╛рде рд╕рдЬрд╛рдП рдЧрдП рд╣реИрдВ, рд╕рд┐рд╡рд╛рдп рдЗрд╕рдХреЗ рдХрд┐ рд╡реЗ рдирд╣реАрдВ рд╣реИрдВред (
__new__
рдПрдХ рд╡рд░реНрдЧ рдХреЗ рдирдП рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рддрд╛ рд╣реИ,
__init_subclass__
рдПрдХ рд╣реБрдХ рд╣реИ рдЬрд┐рд╕реЗ рддрдм рд╡реНрдпреБрддреНрдкрдиреНрди рд╡рд░реНрдЧ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред)
class Foo: def __new__(cls, *args, **kwargs): print(cls) return super().__new__( cls, *args, **kwargs ) Foo()
рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╕рдВрджрд░реНрдн рдкреНрд░рдмрдВрдзрдХ
рдпрджрд┐ рдЖрдк рд╕рдВрджрд░реНрдн рдкреНрд░рдмрдВрдзрдХ рдХреЛ рд╕рдВрджрд░реНрдн рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд░рдиреЗ рдпрд╛ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ рдкрд░ рдХреЛрд░рдЯрд╛рдЗрди рдХреЛ рдирд┐рд▓рдВрдмрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╕рдВрджрд░реНрдн рдкреНрд░рдмрдВрдзрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп
m.__enter__()
рдФрд░
m.__exit__()
рдкрд╛рдпрдерди рдХрд░рддрд╛ рд╣реИред
m.__aenter__()
рдФрд░ рдкреНрд░рддреАрдХреНрд╖рд╛
m.__aexit__()
рдХреНрд░рдорд╢рдГред
рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд╕рдВрджрд░реНрдн рдкреНрд░рдмрдВрдзрдХреЛрдВ рдХреЛ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЗ рд╕рд╛рде async рдХреЗ рд╕рд╛рде рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:
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())
рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╕рдВрджрд░реНрдн рдкреНрд░рдмрдВрдзрдХ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдирд╛
рдкрд╛рдЗрдерди 3.7 рдХреЗ рдмрд╛рдж рд╕реЗ,
contextlib
asynccontextmanager
рдбреЗрдХреЛрд░реЗрдЯрд░ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕
asynccontextmanager
рдореИрдиреЗрдЬрд░ рдХреЛ рдареАрдХ рдЙрд╕реА рддрд░реАрдХреЗ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ,
contextlib
рд╕реЗ
asynccontextmanager
рдХрд░рддрд╛ рд╣реИ:
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
рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдпреВрдирд░реА рдкреНрд▓рд╕ рдСрдкрд░реЗрдЯрд░
рдкрд╛рдпрдерди рдореЗрдВ рдХреЛрдИ
++
рдСрдкрд░реЗрдЯрд░ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рдХреЗ рдмрдЬрд╛рдп
x += 1
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐,
++x
рдЕрднреА рднреА рдПрдХ рд╡реИрдз рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рд╣реИ (рд▓реЗрдХрд┐рди
x++
рдирд╣реАрдВ рд╣реИ)ред
рдХреИрдЪ рдкрд╛рдЗрдерди рдХрд╛ рдЕрдкрд░ рдкреНрд▓рд╕ рдСрдкрд░реЗрдЯрд░ рд╣реИ, рдФрд░
++x
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ
x.__pos__().__pos__()
ред рд╣рдо рдЗрд╕ рддрдереНрдп рдХрд╛ рджреБрд░реБрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ ++ рд╡реГрджреНрдзрд┐ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЕрдиреБрд╢рдВрд╕рд┐рдд рдирд╣реАрдВ):
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)
рдЬрд╛рджреВ рдХреА рд╡рд╕реНрддреБ
MagicMock
рдСрдмреНрдЬреЗрдХреНрдЯ рдЖрдкрдХреЛ рдХрд┐рд╕реА рднреА рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдпрд╛ рдХрд┐рд╕реА рднреА рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЗрд╕ рддрд░рд╣ рдХреЗ рдЙрдкрдпреЛрдЧ рдкрд░ рдирдпрд╛ рдореЙрдХ рд╡рд╛рдкрд╕ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдХреНрдпрд╛ рдЕрдзрд┐рдХ рд╣реИ, рдЖрдк рдПрдХ рд╣реА рдирдХрд▓реА рд╡рд╕реНрддреБ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ рдпрджрд┐ рдЙрд╕реА рд╡рд┐рд╢реЗрд╖рддрд╛ рддрдХ рдкрд╣реБрдВрдЪрддреЗ рд╣реИрдВ (рдпрд╛ рдЙрд╕реА рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ):
>>> 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]
рд╕рд╛рде рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХрд╛ рдХрд╛рд░рдг рдпрд╣ рд╣реИ рдХрд┐,
MagicMock
рджреНрд╡рд╛рд░рд╛ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЖрдЗрдЯрдо рдПрдХреНрд╕реЗрд╕ рдХрд╛ рдЗрд▓рд╛рдЬ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдпрд╣ рдХреЗрд╡рд▓ рдПрдХ рд╡рд┐рдзрд┐ рдХреЙрд▓ рд╣реИ:
>>> 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