@Pythonetc рдЬрдирд╡рд░реА 2019



рдпрд╣ рдореЗрд░реА @pythonetc рдлреАрдб рд╕реЗ рдкрд╛рдпрдерди рдЯрд┐рдкреНрд╕ рдФрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХрд╛ рдЖрдард╡рд╛рдБ рдЪрдпрди рд╣реИред

рдкрд┐рдЫрд▓реЗ рдЪрдпрди:



рджреЛ рдирд┐рд╣рд┐рдд рд╡рд░реНрдЧ рд╡рд┐рдзрд┐рдпрд╛рдБ


рдПрдХ рд╡рд░реНрдЧ рд╡рд┐рдзрд┐ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ @classmethod рдбреЗрдХреЛрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдлрд┐рд░ рдЗрд╕ рд╡рд┐рдзрд┐ рдХреЛ рд╕реАрдзреЗ рд╡рд░реНрдЧ рд╕реЗ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рди рдХрд┐ рдЗрд╕рдХреЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рд╕реЗ, рдФрд░ рдпрд╣ рдХрдХреНрд╖рд╛ рдХреЛ рдкрд╣рд▓реЗ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЗрдЧрд╛ (рдЗрд╕реЗ рдЖрдорддреМрд░ рдкрд░ cls рджреНрд╡рд╛рд░рд╛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, self рдирд╣реАрдВ)ред

рд╣рд╛рд▓рд╛рдБрдХрд┐, рдкрд╛рдпрдерди рдбреЗрдЯрд╛ рдореЙрдбрд▓ рдореЗрдВ рджреЛ рдирд┐рд╣рд┐рдд рд╡рд░реНрдЧ рд╡рд┐рдзрд┐рдпрд╛рдБ рд╣реИрдВ: __new__ рдФрд░ __init_subclass__ ред рд╡реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ рдЬреИрд╕реЗ рдХрд┐ рдЙрдиреНрд╣реЗрдВ __new__ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ @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 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()) 

рдПрдХ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╕рдВрджрд░реНрдн рдкреНрд░рдмрдВрдзрдХ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдирд╛


рдкрд╛рдпрдерди 3.7 рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрдиреЗ рдкрд░, contextlib рдПрдХ asynccontextmanager рдбреЗрдХреЛрд░реЗрдЯрд░ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдЙрд╕реА рддрд░рд╣ рдПрдХ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╕рдВрджрд░реНрдн рдкреНрд░рдмрдВрдзрдХ рдХреЛ рдЙрд╕реА рддрд░рд╣ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдЬреИрд╕реЗ рдХрд┐ 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 рдСрдмреНрдЬреЗрдХреНрдЯ 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/hi438778/


All Articles