рдореЗрд░реЗ рдЯреЗрд▓реАрдЧреНрд░рд╛рдо-рдЪреИрдирд▓ @pythonetc рд╕реЗ рдЯрд┐рдкреНрд╕ рдПрдВрдб рдЯреНрд░рд┐рдХреНрд╕, рдЬрдирд╡рд░реА 2019



рдпрд╣ рдореЗрд░реЗ рдЯреЗрд▓реАрдЧреНрд░рд╛рдо-рдЪреИрдирд▓ @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() # <class '__main__.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) # 4 ++x print(x) # 5 

рдЬрд╛рджреВ рдХреА рд╡рд╕реНрддреБ


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 

Source: https://habr.com/ru/post/hi438776/


All Articles