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


рдпрд╣ рдореЗрд░реЗ рдЯреЗрд▓реАрдЧреНрд░рд╛рдо-рдЪреИрдирд▓ @pythonetc рд╕реЗ рдкрд╛рдпрдерди рдФрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реБрдЭрд╛рд╡реЛрдВ рдФрд░ рдЯреНрд░рд┐рдХреНрд╕ рдХрд╛ рдПрдХ рдирдпрд╛ рдЪрдпрди рд╣реИред

Ations рдкрд┐рдЫрд▓рд╛ рдкреНрд░рдХрд╛рд╢рди


рдЖрдк рдмрд╕ рдЙрдиреНрд╣реЗрдВ рдЕрд╕рд╛рдЗрди рдХрд░рдХреЗ рдХреНрд▓реЛрдЬрд░ рд╡реИрд░рд┐рдПрдмрд▓ рдХреЛ рдореНрдпреВрдЯ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред рдкрд╛рдпрдерди рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рдХреЛ рдПрдХ рдлрдВрдХреНрд╢рди рдмреЙрдбреА рдХреЗ рдЕрдВрджрд░ рдПрдХ рдкрд░рд┐рднрд╛рд╖рд╛ рдорд╛рдирддрд╛ рд╣реИ рдФрд░ рдмрд┐рд▓реНрдХреБрд▓ рдмрдВрдж рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

рдареАрдХ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдкреНрд░рд┐рдВрдЯ 2 :

 def make_closure(x): def closure(): print(x) return closure make_closure(2) 

UnboundLocalError: local variable 'x' referenced before assignment рдлреЗрдВрдХрддрд╛ рд╣реИ UnboundLocalError: local variable 'x' referenced before assignment :

 def make_closure(x): def closure(): print(x) x *= 2 print(x) return closure make_closure(2)() 


рдЗрд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ nonlocal рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╡реНрдпрд╛рдЦреНрдпрд╛рдХрд╛рд░ рдХреЛ рдПрдХ рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рддрд╛ рд╣реИ:

 def make_closure(x): def closure(): nonlocal x print(x) x *= 2 print(x) return closure make_closure(2)() 


рдХрднреА-рдХрднреА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреЗ рджреМрд░рд╛рди рдЖрдк рдЬрд╛рдирдирд╛ рдЪрд╛рд╣ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдпрд╣ рдЪрд▓рдирд╛ рдХрд╛ рдкрд╣рд▓рд╛ рдпрд╛ рдЕрдВрддрд┐рдо рддрддреНрд╡ рд╣реИред рдЗрд╕реЗ рд╕рдВрднрд╛рд▓рдиреЗ рдХрд╛ рд╕рд░рд▓ рддрд░реАрдХрд╛ рд╕реНрдкрд╖реНрдЯ рдзреНрд╡рдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ:

 def sparse_list(iterable, num_of_zeros=1): result = [] zeros = [0 for _ in range(num_of_zeros)] first = True for x in iterable: if not first: result += zeros result.append(x) first = False return result assert sparse_list([1, 2, 3], 2) == [ 1, 0, 0, 2, 0, 0, 3, ] 

рдЖрдк рдкрд╣рд▓реЗ рддрддреНрд╡ рдХреЛ рд▓реВрдк рдХреЗ рдмрд╛рд╣рд░ рднреА рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдЕрдзрд┐рдХ рд╕реНрдкрд╖реНрдЯ рд▓рдЧ рд╕рдХрддрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдХреБрдЫ рд╣рдж рддрдХ рдХреЛрдб рджреЛрд╣рд░рд╛рд╡ рдХреА рдУрд░ рдЬрд╛рддрд╛ рд╣реИред рдЕрдореВрд░реНрдд рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рднреА рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдмрд╛рдд рдирд╣реАрдВ рд╣реИ:

 def sparse_list(iterable, num_of_zeros=1): result = [] zeros = [0 for _ in range(num_of_zeros)] iterator = iter(iterable) try: result.append(next(iterator)) except StopIteration: return [] for x in iterator: result += zeros result.append(x) return result 

рдЖрдк i == 0 рд▓рд┐рдП enumerate рдФрд░ рдЪреЗрдХ рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдХреЗрд╡рд▓ рдкрд╣рд▓реЗ рддрддреНрд╡ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЕрдВрддрд┐рдо рд╡рд╛рд▓реЗ рдкрд░ рдирд╣реАрдВ), рд▓реЗрдХрд┐рди рдЕрдВрддрд┐рдо рд╕рдорд╛рдзрд╛рди рдПрдХ рдЬрдирд░реЗрдЯрд░ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ first рдФрд░ last рдЭрдВрдбреЗ рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдПрдХ рддрддреНрд╡ рдХреЗ рддрддреНрд╡ рдХреЛ рд▓реМрдЯрд╛рддрд╛ рд╣реИ iterable:

 def first_last_iter(iterable): iterator = iter(iterable) first = True last = False while not last: if first: try: current = next(iterator) except StopIteration: return else: current = next_one try: next_one = next(iterator) except StopIteration: last = True yield (first, last, current) first = False 

рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдХрд╛рд░реНрдп рдЕрдм рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:

 def sparse_list(iterable, num_of_zeros=1): result = [] zeros = [0 for _ in range(num_of_zeros)] for first, last, x in first_last_iter(iterable): if not first: result += zeros result.append(x) return result 


рдпрджрд┐ рдЖрдк рджреЛ рдШрдЯрдирд╛рдУрдВ рдХреЗ рдмреАрдЪ рд╕рдордп рдХреЛ рдорд╛рдкрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рд╕рдордп рдХреЗ рдмрдЬрд╛рдп time.monotonic() рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред time.monotonic() рд╕рд┐рд╕реНрдЯрдо рдШрдбрд╝реА рдЕрдкрдбреЗрдЯ рд╣реЛрдиреЗ рдкрд░ рднреА рдХрднреА рдкреАрдЫреЗ рдирд╣реАрдВ рдЬрд╛рддреА рд╣реИ:

 from contextlib import contextmanager import time @contextmanager def timeit(): start = time.monotonic() yield print(time.monotonic() - start) def main(): with timeit(): time.sleep(2) main() 


рдиреЗрд╕реНрдЯреЗрдб рд╕рдВрджрд░реНрдн рдкреНрд░рдмрдВрдзрдХреЛрдВ рдХреЛ рдЖрдорддреМрд░ рдкрд░ рдкрддрд╛ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рд╡реЗ рдиреЗрд╕реНрдЯреЗрдб рд╣реИрдВред рдЖрдк рдЙрдиреНрд╣реЗрдВ рдмрд╛рд╣рд░реА рд╕рдВрджрд░реНрдн рджреНрд╡рд╛рд░рд╛ рдЖрдВрддрд░рд┐рдХ рд╕рдВрджрд░реНрдн рдкреНрд░рдмрдВрдзрдХреЛрдВ рдХреЛ рдмрддрд╛рдХрд░ рдЬрд╛рди рд╕рдХрддреЗ рд╣реИрдВ:

 from contextlib import AbstractContextManager import time class TimeItContextManager(AbstractContextManager): def __init__(self, name, parent=None): super().__init__() self._name = name self._parent = parent self._start = None self._substracted = 0 def __enter__(self): self._start = time.monotonic() return self def __exit__(self, exc_type, exc_value, traceback): delta = time.monotonic() - self._start if self._parent is not None: self._parent.substract(delta) print(self._name, 'total', delta) print(self._name, 'outer', delta - self._substracted) return False def child(self, name): return type(self)(name, parent=self) def substract(self, n): self._substracted += n timeit = TimeItContextManager def main(): with timeit('large') as large_t: with large_t.child('medium') as medium_t: with medium_t.child('small-1'): time.sleep(1) with medium_t.child('small-2'): time.sleep(1) time.sleep(1) time.sleep(1) main() 


рдпрджрд┐ рдЖрдк рдХреЙрд▓ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЗ рдиреАрдЪреЗ рдХреБрдЫ рдЬрд╛рдирдХрд╛рд░реА рдкрд╛рд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЖрдорддреМрд░ рдкрд░ рд╕рдмрд╕реЗ рд╕рд░рд▓ рддрд░реАрдХреЗ рд╕реЗ рд╕рдВрднрд╡ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ: рдЖрдк рдЗрд╕реЗ рдХрд╛рд░реНрдп рддрд░реНрдХреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред

рд╣рд╛рд▓рд╛рдВрдХрд┐, рдХреБрдЫ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдбреЗрдЯрд╛ рдХреЗ рдХреБрдЫ рдирдП рдЯреБрдХрдбрд╝реЗ рдХреЛ рдлреИрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЗ рд╕рднреА рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрддреНрдпрдзрд┐рдХ рдЕрд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рдЖрдк рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЗ рд╕рднреА рдХрд╛рд░реНрдпреЛрдВ рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рдВрджрд░реНрдн рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕ рд╕рдВрджрд░реНрдн рдХреЛ рддрдХрдиреАрдХреА рд░реВрдк рд╕реЗ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ?

рд╕рдмрд╕реЗ рд╕рд░рд▓ рд╕рдорд╛рдзрд╛рди рдПрдХ рд╡реИрд╢реНрд╡рд┐рдХ рдЪрд░ рд╣реИред рдкрд╛рдпрдерди рдореЗрдВ, рдЖрдк рд╕рдВрджрд░реНрдн рдзрд╛рд░рдХреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдореЙрдбреНрдпреВрд▓ рдФрд░ рдХрдХреНрд╖рд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рд╣реИрдВ, рдХрдбрд╝рд╛рдИ рд╕реЗ рдмреЛрд▓рдиреЗ рд╡рд╛рд▓реЗ, рд╡реИрд╢реНрд╡рд┐рдХ рдЪрд░ рднреАред рдЖрдк рд╢рд╛рдпрдж рд▓реЙрдЧрд░ рдЬреИрд╕реА рдЪреАрдЬреЛрдВ рдХреЗ рд▓рд┐рдП рджреИрдирд┐рдХ рдЖрдзрд╛рд░ рдкрд░ рдХрд░рддреЗ рд╣реИрдВред

рдпрджрд┐ рдЖрдкрдХрд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрд╣реБ-рдереНрд░реЗрдбреЗрдб рд╣реИ, рддреЛ рдирдВрдЧреЗ рд╡реИрд╢реНрд╡рд┐рдХ рдЪрд░ рдЖрдкрдХреЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдереНрд░реЗрдб-рд╕реБрд░рдХреНрд╖рд┐рдд рдирд╣реАрдВ рд╣реИрдВред рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдХреЙрд▓ рдЪреЗрди рдЪрд▓ рд╕рдХрддреА рд╣реИрдВ, рдФрд░ рдЙрдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреЛ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рд╕рдВрджрд░реНрдн рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред threading рдореЙрдбреНрдпреВрд▓ рдЖрдкрдХреЛ рдХрд╡рд░ рдХрд░рддрд╛ рд╣реИ, рдпрд╣ threading.local() рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред threading.local() рдСрдмреНрдЬреЗрдХреНрдЯ рдЬреЛ рдереНрд░реЗрдб-рд╕реБрд░рдХреНрд╖рд┐рдд рд╣реИред рдХреЗрд╡рд▓ рдПрд╕реЗрд╕рд┐рдВрдЧ рдПрдХреНрд╕реЗрд╕ рджреНрд╡рд╛рд░рд╛ рдХреЛрдИ рдбреЗрдЯрд╛ threading.local().symbol = '@' : threading.local().symbol = '@' ред

рдлрд┐рд░ рднреА, рджреЛрдиреЛрдВ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕рдВрдХреНрд╖рд┐рдкреНрдд-рдЕрд╕реБрд░рдХреНрд╖рд┐рдд рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд╡реЗ рдХреЛрд░рдЯреАрди рдХреЙрд▓-рдЪреЗрди рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ, рдЬрд╣рд╛рдВ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рди рдХреЗрд╡рд▓ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рдкреНрд░рддреАрдХреНрд╖рд╛ рднреА рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИред рдПрдХ рдмрд╛рд░ рдПрдХ рдХреЛрд░рдЖрдЙрдЯ рдХрд╛ await , рдПрдХ рдЗрд╡реЗрдВрдЯ рд▓реВрдк рдПрдХ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рд╢реНрд░реГрдВрдЦрд▓рд╛ рд╕реЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рдХреЙрд░рдЖрдЙрдЯ рдЪрд▓рд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛:

 import asyncio import sys global_symbol = '.' async def indication(timeout): while True: print(global_symbol, end='') sys.stdout.flush() await asyncio.sleep(timeout) async def sleep(t, indication_t, symbol='.'): loop = asyncio.get_event_loop() global global_symbol global_symbol = symbol task = loop.create_task( indication(indication_t) ) await asyncio.sleep(t) task.cancel() loop = asyncio.get_event_loop() loop.run_until_complete(asyncio.gather( sleep(1, 0.1, '0'), sleep(1, 0.1, 'a'), sleep(1, 0.1, 'b'), sleep(1, 0.1, 'c'), )) 

рдЖрдк рд▓реВрдк рд╕реЗрдЯ рдХрд░рдХреЗ рдФрд░ рдХреЙрд░рдЯреЙрдпрдиреНрд╕ рдХреЗ рдмреАрдЪ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХреЗ рд╕рдВрджрд░реНрдн рдХреЛ рд╣рд░ рдмрд╛рд░ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдк рдЗрд╕реЗ Python 3.7 рдХреЗ рдмрд╛рдж рд╕реЗ contextvars рдореЙрдбреНрдпреВрд▓ рдХреЗ рд╕рд╛рде рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

 import asyncio import sys import contextvars global_symbol = contextvars.ContextVar('symbol') async def indication(timeout): while True: print(global_symbol.get(), end='') sys.stdout.flush() await asyncio.sleep(timeout) async def sleep(t, indication_t, symbol='.'): loop = asyncio.get_event_loop() global_symbol.set(symbol) task = loop.create_task(indication(indication_t)) await asyncio.sleep(t) task.cancel() loop = asyncio.get_event_loop() loop.run_until_complete(asyncio.gather( sleep(1, 0.1, '0'), sleep(1, 0.1, 'a'), sleep(1, 0.1, 'b'), sleep(1, 0.1, 'c'), )) 

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


All Articles