@Pythonetc рд╕рдВрдХрд▓рди, рдЬреБрд▓рд╛рдИ 2019


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

тЖР рдкрд┐рдЫрд▓рд╛ рд╕рдВрдЧреНрд░рд╣


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

рдареАрдХ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, 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, ] 

рдмреЗрд╢рдХ, рдЖрдк рдкрд╣рд▓реЗ рддрддреНрд╡ рдХреЛ рд▓реВрдк рдХреЗ рдмрд╛рд╣рд░ рд╕рдВрднрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдХреНрд▓реАрдирд░ рджрд┐рдЦрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдВрд╢рд┐рдХ рдХреЛрдб рджреЛрд╣рд░рд╛рд╡ рдХреА рдУрд░ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЕрдореВрд░реНрдд iterable рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп рдРрд╕рд╛ рдХрд░рдирд╛ рдЗрддрдирд╛ рдЖрд╕рд╛рди рдирд╣реАрдВ рд╣реЛрдЧрд╛:

 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 

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

 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() рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред 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 = '@' ред

рд╣рд╛рд▓рд╛рдВрдХрд┐, рджреЛрдиреЛрдВ рд╡рд░реНрдгрд┐рдд рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕рдВрдЧрд╛рдорд┐рддрд┐-рд╕реБрд░рдХреНрд╖рд┐рдд рдирд╣реАрдВ рд╣реИрдВ, рдЕрд░реНрдерд╛рддреН, рд╡реЗ рдХреЛрд░рдЖрдЙрдЯ рдХреЙрд▓ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдирд╣реАрдВ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ рд╕рд┐рд╕реНрдЯрдо рди рдХреЗрд╡рд▓ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рдЙрдиреНрд╣реЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреА рднреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реИред рдЬрдм рдХреЛрдИ рдХреЛрд░рдЯрд╛рдЗрди 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'), )) 

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

 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/hi462311/


All Articles