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

рдЫрд╡рд┐

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

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

рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреА рддреБрд▓рдирд╛


рдХрднреА-рдХрднреА рдЖрдк рдХреБрдЫ рдореВрд▓реНрдпреЛрдВ рдХреА рдЕрдирджреЗрдЦреА рдХрд░ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдЬрдЯрд┐рд▓ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдЖрдорддреМрд░ рдкрд░, рдпрд╣ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд╕рд╛рде рд╡рд┐рд╢реЗрд╖ рдореВрд▓реНрдпреЛрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

>>> d = dict(a=1, b=2, c=3) >>> assert d['a'] == 1 >>> assert d['c'] == 3 

рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЖрдк рд╡рд┐рд╢реЗрд╖ рдореВрд▓реНрдп рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рдореВрд▓реНрдп рдХреЗ рдмрд░рд╛рдмрд░ рд╣реЛрдиреЗ рдХреА рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рддрд╛ рд╣реИ:

 >>> assert d == dict(a=1, b=ANY, c=3) 

рдЗрд╕реЗ __eq__ рд╡рд┐рдзрд┐ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдХреЗ рдЖрд╕рд╛рдиреА рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

 >>> class AnyClass: ... def __eq__(self, another): ... return True ... >>> ANY = AnyClass() 

sys.stdout рдПрдХ рд░реИрдкрд░ рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдХрдЪреНрдЪреЗ рдмрд╛рдЗрдЯреНрд╕ рдХреЗ рдмрдЬрд╛рдп рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рд▓рд┐рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рд╕реНрдЯреНрд░рд┐рдВрдЧ sys.stdout.encoding рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдПрдиреНрдХреЛрдб рдХрд┐рдпрд╛ sys.stdout.encoding :

 >>> _ = sys.stdout.write('Stra├Яe\n') Stra├Яe >>> sys.stdout.encoding 'UTF-8' 

sys.stdout.encoding рдХреЗрд╡рд▓-рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ рдФрд░ рдкрд╛рдпрдерди рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдПрдиреНрдХреЛрдбрд┐рдВрдЧ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ, рдЬрд┐рд╕реЗ PYTHONIOENCODING рд╡рд╛рддрд╛рд╡рд░рдг рдЪрд░ рд╕реЗрдЯ рдХрд░рдХреЗ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

 $ PYTHONIOENCODING=cp1251 python3 Python 3.6.6 (default, Aug 13 2018, 18:24:23) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import sys >>> sys.stdout.encoding 'cp1251' 

рдпрджрд┐ рдЖрдк рдмрд╛рдЗрдЯреНрд╕ рдХреЛ stdout рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рдЖрдк рд▓рд┐рдкрдЯреЗ рдмрдлрд░ рдХреЛ sys.stdout.buffer рд╕рд╛рде рдПрдХреНрд╕реЗрд╕ рдХрд░рдХреЗ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдПрдиреНрдХреЛрдбрд┐рдВрдЧ рдХреЛ рдмрд╛рдпрдкрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 >>> sys.stdout <_io.TextIOWrapper name='<stdout>' mode='w' encoding='cp1251'> >>> sys.stdout.buffer <_io.BufferedWriter name='<stdout>'> >>> _ = sys.stdout.buffer.write(b'Stra\xc3\x9fe\n') Stra├Яe 

sys.stdout.buffer рднреА рдПрдХ рд░реИрдкрд░ рд╣реИ рдЬреЛ рдЖрдкрдХреЗ рд▓рд┐рдП рдмрдлрд░рд┐рдВрдЧ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдХрдЪреНрдЪреЗ рдлрд╝рд╛рдЗрд▓ рд╣реИрдВрдбрд▓рд░ рдХреЛ sys.stdout.buffer.raw рд╕рд╛рде рдПрдХреНрд╕реЗрд╕ рдХрд░рдХреЗ рдмрд╛рдИрдкрд╛рд╕ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

 >>> _ = sys.stdout.buffer.raw.write(b'Stra\xc3\x9fe') Stra├Яe 

рдПрд▓рд┐рдкреНрд╕рд┐рд╕ рдирд┐рд░рдВрддрд░


рдкрд╛рдпрдерди рдореЗрдВ рдирд┐рд░реНрдорд┐рдд рд╕реНрдерд┐рд░рд╛рдВрдХ рдХреА рдПрдХ рдмрд╣реБрдд рдЫреЛрдЯреА рд╕реВрдЪреА рд╣реИред рдЙрдирдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ Ellipsis рдЬрд┐рд╕реЗ рд▓рд┐рдЦрд╛ рднреА рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ... рдЗрд╕ рд╕реНрдерд┐рд░рд╛рдВрдХ рдХрд╛ рджреБрднрд╛рд╖рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рд╡рд┐рд╢реЗрд╖ рдЕрд░реНрде рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЙрди рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдЗрд╕ рддрд░рд╣ рдХреЗ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдЙрдкрдпреБрдХреНрдд рд╣реЛрддреЗ рд╣реИрдВред

рдПрдХ __getitem__ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ numpy рд╕рдорд░реНрдерди __getitem__ , рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП x[...] x рд╕рднреА рддрддреНрд╡реЛрдВ рдХреЛ рд▓реМрдЯрд╛рддрд╛ рд╣реИред

рдкреАрдИрдкреА 484 рдЕрддрд┐рд░рд┐рдХреНрдд рдЕрд░реНрде рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ: Callable[..., type] рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдХреЙрд▓рдмреИрд▓ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдХреЛрдИ рддрд░реНрдХ рдкреНрд░рдХрд╛рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рд╣реИред

рдЕрдВрдд рдореЗрдВ, рдЖрдк рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ ... рдпрд╣ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдлрд╝рдВрдХреНрд╢рди рдЕрднреА рддрдХ рд▓рд╛рдЧреВ рдирд╣реАрдВ рд╣реБрдЖ рд╣реИред рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╡реИрдз рдкрд╛рдпрдерди рдХреЛрдб рд╣реИ:

 def x(): ... 

рд╣рд╛рд▓рд╛рдБрдХрд┐, рдкрд╛рдпрдерди 2 рдореЗрдВ Ellipsis рдХреЛ рдирд╣реАрдВ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ... рдПрдХрдорд╛рддреНрд░ рдЕрдкрд╡рд╛рдж a[...] рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде a[Ellpsis] ред

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рднреА рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдкрд╛рдпрдерди 3 рдХреЗ рд▓рд┐рдП рдорд╛рдиреНрдп рд╣реИрдВ, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рдкрд╣рд▓реА рдкрдВрдХреНрддрд┐ рдкрд╛рдпрдерди 2 рдХреЗ рд▓рд┐рдП рдорд╛рдиреНрдп рд╣реИ:

 a[...] a[...:2:...] [..., ...] {...:...} a = ... ... is ... def a(x=...): ... 

рдореЙрдбреНрдпреВрд▓ рдкреБрдирдГрдкреВрд░реНрддрд┐


рдкрд╣рд▓реЗ рд╕реЗ рдЖрдпрд╛рддрд┐рдд рдореЙрдбреНрдпреВрд▓ рдлрд┐рд░ рд╕реЗ рд▓реЛрдб рдирд╣реАрдВ рд╣реЛрдВрдЧреЗред import foo рд╕рд┐рд░реНрдл рдХреБрдЫ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рдПрдХ рд╕рдВрд╡рд╛рджрд╛рддреНрдордХ рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп рдореЙрдбреНрдпреВрд▓ рдХреЛ рдкреБрди: рдЖрдпрд╛рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╕рд╛рдмрд┐рдд рд╣реБрдЖред рдкрд╛рдпрдерди importlib рдореЗрдВ рдРрд╕рд╛ рдХрд░рдиреЗ рдХрд╛ рдЙрдЪрд┐рдд рддрд░реАрдХрд╛ рд╣реИ importlib :

 In [1]: import importlib In [2]: with open('foo.py', 'w') as f: ...: f.write('a = 1') ...: In [3]: import foo In [4]: foo.a Out[4]: 1 In [5]: with open('foo.py', 'w') as f: ...: f.write('a = 2') ...: In [6]: foo.a Out[6]: 1 In [7]: import foo In [8]: foo.a Out[8]: 1 In [9]: importlib.reload(foo) Out[9]: <module 'foo' from '/home/v.pushtaev/foo.py'> In [10]: foo.a Out[10]: 2 

ipython рдореЗрдВ autoreload рдПрдХреНрд╕рдЯреЗрдВрд╢рди рднреА рд╣реИ рдЬреЛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдиреЗ рдкрд░ рдореЙрдбреНрдпреВрд▓ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ autoreload : рдЖрдпрд╛рдд рдХрд░рддрд╛ рд╣реИ:

 In [1]: %load_ext autoreload In [2]: %autoreload 2 In [3]: with open('foo.py', 'w') as f: ...: f.write('print("LOADED"); a=1') ...: In [4]: import foo LOADED In [5]: foo.a Out[5]: 1 In [6]: with open('foo.py', 'w') as f: ...: f.write('print("LOADED"); a=2') ...: In [7]: import foo LOADED In [8]: foo.a Out[8]: 2 In [9]: with open('foo.py', 'w') as f: ...: f.write('print("LOADED"); a=3') ...: In [10]: foo.a LOADED Out[10]: 3 

\ _ рдЬреА


рдХреБрдЫ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ, рдЖрдк \G рдЕрднрд┐рдХрдерди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдЙрд╕ рд╕реНрдерд┐рддрд┐ рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдкрд┐рдЫрд▓рд╛ рдореИрдЪ рд╕рдорд╛рдкреНрдд рд╣реБрдЖ рд╣реИред рдпрд╣ рдкрд░рд┐рдорд┐рдд рдСрдЯреЛрдореЗрдЯрд╛ рд▓рд┐рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдЬреЛ рд╢рдмреНрдж рджреНрд╡рд╛рд░рд╛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рдмреНрдж рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрд▓рддреЗ рд╣реИрдВ (рдЬрд╣рд╛рдВ рд╢рдмреНрдж рд░реЗрдЧреЗрдХреНрд╕ рджреНрд╡рд╛рд░рд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ)ред

рд╣рд╛рд▓рд╛рдБрдХрд┐, рдкрд╛рдпрдерди рдореЗрдВ рдРрд╕реА рдХреЛрдИ рдмрд╛рдд рдирд╣реАрдВ рд╣реИред рдЙрдЪрд┐рдд рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рд╕реНрдерд┐рддрд┐ рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдЯреНрд░реИрдХ рдХрд░рдирд╛ рдФрд░ rexx рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╡рд┐рдХрд▓реНрдк рдХреЛ рдкрд╛рд╕ рдХрд░рдирд╛ рд╣реИ:

 import re import json text = '<a><b>foo</b><c>bar</c></a><z>bar</z>' regex = '^(?:<([az]+)>|</([az]+)>|([az]+))' stack = [] tree = [] pos = 0 while len(text) > pos: error = f'Error at {text[pos:]}' found = re.search(regex, text[pos:]) assert found, error pos += len(found[0]) start, stop, data = found.groups() if start: tree.append(dict( tag=start, children=[], )) stack.append(tree) tree = tree[-1]['children'] elif stop: tree = stack.pop() assert tree[-1]['tag'] == stop, error if not tree[-1]['children']: tree[-1].pop('children') elif data: stack[-1][-1]['data'] = data print(json.dumps(tree, indent=4)) 

рдкрд┐рдЫрд▓реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╣рдо рдмрд╛рд░-рдмрд╛рд░ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рд╕реНрд▓рд╛рдЗрд╕ рдХрд░рдиреЗ рд╕реЗ рдмрдЪрд╛рдХрд░ рдХреБрдЫ рд╕рдордп рдмрдЪрд╛ рд╕рдХрддреЗ рд╣реИрдВ рд▓реЗрдХрд┐рди рдкреБрдирдГ рдореЙрдбреНрдпреВрд▓ рдХреЛ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдПрдХ рдЕрд▓рдЧ рд╕реНрдерд┐рддрд┐ рд╕реЗ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЦреЛрдЬ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВред

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

 import re import json text = '<a><b>foo</b><c>bar</c></a><z>bar</z>' * 10 def print_tree(tree): print(json.dumps(tree, indent=4)) def xml_to_tree_slow(text): regex = '^(?:<([az]+)>|</([az]+)>|([az]+))' stack = [] tree = [] pos = 0 while len(text) > pos: error = f'Error at {text[pos:]}' found = re.search(regex, text[pos:]) assert found, error pos += len(found[0]) start, stop, data = found.groups() if start: tree.append(dict( tag=start, children=[], )) stack.append(tree) tree = tree[-1]['children'] elif stop: tree = stack.pop() assert tree[-1]['tag'] == stop, error if not tree[-1]['children']: tree[-1].pop('children') elif data: stack[-1][-1]['data'] = data def xml_to_tree_slow(text): regex = '^(?:<([az]+)>|</([az]+)>|([az]+))' stack = [] tree = [] pos = 0 while len(text) > pos: error = f'Error at {text[pos:]}' found = re.search(regex, text[pos:]) assert found, error pos += len(found[0]) start, stop, data = found.groups() if start: tree.append(dict( tag=start, children=[], )) stack.append(tree) tree = tree[-1]['children'] elif stop: tree = stack.pop() assert tree[-1]['tag'] == stop, error if not tree[-1]['children']: tree[-1].pop('children') elif data: stack[-1][-1]['data'] = data return tree _regex = re.compile('(?:<([az]+)>|</([az]+)>|([az]+))') def _error_message(text, pos): return text[pos:] def xml_to_tree_fast(text): stack = [] tree = [] pos = 0 while len(text) > pos: error = f'Error at {text[pos:]}' found = _regex.search(text, pos=pos) begin, end = found.span(0) assert begin == pos, _error_message(text, pos) assert found, _error_message(text, pos) pos += len(found[0]) start, stop, data = found.groups() if start: tree.append(dict( tag=start, children=[], )) stack.append(tree) tree = tree[-1]['children'] elif stop: tree = stack.pop() assert tree[-1]['tag'] == stop, _error_message(text, pos) if not tree[-1]['children']: tree[-1].pop('children') elif data: stack[-1][-1]['data'] = data return tree print_tree(xml_to_tree_fast(text)) 

рдкрд░рд┐рдгрд╛рдо:

 In [1]: from example import * In [2]: %timeit xml_to_tree_slow(text) 356 ┬╡s ┬▒ 16.9 ┬╡s per loop (mean ┬▒ std. dev. of 7 runs, 1000 loops each) In [3]: %timeit xml_to_tree_fast(text) 294 ┬╡s ┬▒ 6.15 ┬╡s per loop (mean ┬▒ std. dev. of 7 runs, 1000 loops each) 

рдЧреЛрд▓ рдлрдВрдХреНрд╢рди


рдЖрдЬ рдХреА рдкреЛрд╕реНрдЯ @itgram_channel рдХреЗ рд▓реЗрдЦрдХ orininium рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдЦреА рдЧрдИ рд╣реИред

round рдлрдВрдХреНрд╢рди рджрд╢рдорд▓рд╡ рдЕрдВрдХреЛрдВ рдореЗрдВ рдХрд┐рд╕реА рджрд┐рдП рдЧрдП рд╕рдЯреАрдХ рдХреЗ рд▓рд┐рдП рдПрдХ рдирдВрдмрд░ рд░рд╛рдЙрдВрдб рдХрд░рддрд╛ рд╣реИред

 >>> round(1.2) 1 >>> round(1.8) 2 >>> round(1.228, 1) 1.2 

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдк рдирдХрд╛рд░рд╛рддреНрдордХ рдкрд░рд┐рд╢реБрджреНрдзрддрд╛ рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 >>> round(413.77, -1) 410.0 >>> round(413.77, -2) 400.0 

рдЗрдирдкреБрдЯ рдирдВрдмрд░ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХрд╛ round рд░рд┐рдЯрд░реНрди рдореВрд▓реНрдп:

 >>> type(round(2, 1)) <class 'int'> >>> type(round(2.0, 1)) <class 'float'> >>> type(round(Decimal(2), 1)) <class 'decimal.Decimal'> >>> type(round(Fraction(2), 1)) <class 'fractions.Fraction'> 

рдЕрдкрдиреА рдЦреБрдж рдХреА рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЖрдк __round__ рд╡рд┐рдзрд┐ рдХреЗ рд╕рд╛рде рдЧреЛрд▓ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 >>> class Number(int): ... def __round__(self, p=-1000): ... return p ... >>> round(Number(2)) -1000 >>> round(Number(2), -2) -2 

рдорд╛рдиреЛрдВ рдХреЛ рдирд┐рдХрдЯрддрдо 10 ** (-precision) рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд▓рд┐рдП рдЧреЛрд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, precision=1 рдорд╛рди 0.1: round(0.63, 1) рдХрдИ рдХреЗ рд▓рд┐рдП рд░рд╛рдЙрдВрдб рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ 0.6 ред рдпрджрд┐ рджреЛ рдЧреБрдгрдХ рд╕рдорд╛рди рд░реВрдк рд╕реЗ рдкрд╛рд╕ рд╣реИрдВ, рддреЛ рдЧреЛрд▓рд╛рдИ рднреА рдкрд╕рдВрдж рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдХреА рдЬрд╛рддреА рд╣реИ:

 >>> round(0.5) 0 >>> round(1.5) 2 

рдХрднреА-рдХрднреА рдЭрд╛рдВрдХрд┐рдпреЛрдВ рдХрд╛ рдЪрдХреНрдХрд░ рд▓рдЧрд╛рдирд╛ рдереЛрдбрд╝рд╛ рдЖрд╢реНрдЪрд░реНрдпрдЬрдирдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ:

 >>> round(2.85, 1) 2.9 

рдРрд╕рд╛ рдЗрд╕рд▓рд┐рдП рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЕрдзрд┐рдХрд╛рдВрд╢ рджрд╢рдорд▓рд╡ рдЕрдВрд╢реЛрдВ рдХреЛ рдПрдХ рдлреНрд▓реЛрдЯ (https://docs.python.org/3.7/tutorial/floatingpoint.html) рдХреЗ рд░реВрдк рдореЗрдВ рдмрд┐рд▓реНрдХреБрд▓ рдирд╣реАрдВ рджрд┐рдЦрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

 >>> format(2.85, '.64f') '2.8500000000000000888178419700125232338905334472656250000000000000' 

рдпрджрд┐ рдЖрдк рдЖрдзрд╛ рдЪрдХреНрдХрд░ decimal.Decimal рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рдЖрдк decimal.Decimal рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

 >>> from decimal import Decimal, ROUND_HALF_UP >>> Decimal(1.5).quantize(0, ROUND_HALF_UP) Decimal('2') >>> Decimal(2.85).quantize(Decimal('1.0'), ROUND_HALF_UP) Decimal('2.9') >>> Decimal(2.84).quantize(Decimal('1.0'), ROUND_HALF_UP) Decimal('2.8') 

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


All Articles