@Pythonetc рдЕрдкреНрд░реИрд▓ 2019



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

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





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

рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ, рдореИрдВ рдПрдХ рд╢рд╣рд░ рд╡рд╕реНрддреБ рдХреЛ рдХреНрд░рдордмрджреНрдз рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛ рдЬрд┐рд╕рдореЗрдВ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреНрд░рдо рдореЗрдВ рд╕рд┐рдЯреА рдСрдмреНрдЬреЗрдХреНрдЯ рд╢рд╛рдорд┐рд▓ рд╣реИрдВред рдЪрд╛рд░ рддрд░реАрдХреЛрдВ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

1. JSONред рдорд╛рдирд╡-рдкрдардиреАрдп, рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рдЖрд╕рд╛рди рд╣реИ, рд▓реЗрдХрд┐рди рдмрд╣реБрдд рд╕рд╛рд░реА рдореЗрдореЛрд░реА рдХрд╛ рдЙрдкрднреЛрдЧ рдХрд░рддрд╛ рд╣реИред YAML рдФрд░ XML рдкреНрд░рд╛рд░реВрдкреЛрдВ рдХреЗ рд▓рд┐рдП рднреА рдпрд╣реА рд╕рдЪ рд╣реИред

class City: def to_dict(self): return dict( name=self._name, country=self._country, lon=self._lon, lat=self._lat, ) class Cities: def __init__(self, cities): self._cities = cities def to_json(self): return json.dumps([ c.to_dict() for c in self._cities ]).encode('utf8') 

2. рдЕрдЪрд╛рд░ред рдпрд╣ рдЕрдиреБрдХреВрд▓рди рдпреЛрдЧреНрдп рдПрдХ рджреЗрд╢реА рдкрд╛рдпрдерди рдЙрдкрдХрд░рдг рд╣реИ, рдЬреЛ JSON рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдХрдо рдореЗрдореЛрд░реА рдХрд╛ рдЙрдкрднреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдиреБрдХрд╕рд╛рди: рдбреЗрдЯрд╛ рдкреБрдирд░реНрдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдЬрдЧрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

 class Cities: def pickle(self): return pickle.dumps(self) 

3. рдкреНрд░реЛрдЯреЛрдмреЙрдлрд╝ (рдФрд░ рдЕрдиреНрдп рдмрд╛рдЗрдирд░реА рд╕реАрд░рд┐рдпрд▓рд╛рдЗрдЬрд╝рд░, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, msgpack)ред рдпрд╣ рдХрдо рдореЗрдореЛрд░реА рдХрд╛ рдЙрдкрднреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдХрд┐рд╕реА рднреА рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рд╕реНрдкрд╖реНрдЯ рдпреЛрдЬрдирд╛ рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ:

 syntax = "proto2"; message City { required string name = 1; required string country = 2; required float lon = 3; required float lat = 4; } message Cities { repeated City cities = 1; } class City: def to_protobuf(self): result = city_pb2.City() result.name = self._name result.country = self._country result.lon = self._lon result.lat = self._lat return result class Cities: def to_protobuf(self): result = city_pb2.Cities() result.cities.extend([ c.to_protobuf() for c in self._cities ]) return result 

4. рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗред рдЖрдк struct рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдбреЗрдЯрд╛ рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдкреИрдХ рдФрд░ рдЕрдирдкреИрдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕ рддрд░рд╣ рдЖрдк рд╕рдмрд╕реЗ рдХрдо рд╕рдВрднрд╡ рдореЗрдореЛрд░реА рдХреА рдЦрдкрдд рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдХрднреА-рдХрднреА protobuf рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реЛрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╕рдВрд╕реНрдХрд░рдг рдФрд░ рд╕реНрдкрд╖реНрдЯ рдпреЛрдЬрдирд╛рдУрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИред

 class City: def to_bytes(self): name_encoded = self._name.encode('utf8') name_length = len(name_encoded) country_encoded = self._country.encode('utf8') country_length = len(country_encoded) return struct.pack( 'BsBsff', name_length, name_encoded, country_length, country_encoded, self._lon, self._lat, ) class Cities: def to_bytes(self): return b''.join( c.to_bytes() for c in self._cities ) 





рдпрджрд┐ рдлрд╝рдВрдХреНрд╢рди рддрд░реНрдХ рдХрд╛ рдХреЛрдИ рднреА рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди None рдФрд░ рдЙрд╕реЗ T рд░реВрдк рдореЗрдВ рдПрдиреЛрдЯреЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ mypy рд╕реНрд╡рддрдГ рд╣реА рдЗрд╕реЗ Optional[T] (рдЕрд░реНрдерд╛рдд, Union[T, None] ) mypy рд▓реЗрдЧрд╛ред

рдпрд╣ рдЕрдиреНрдп рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдк рдХреБрдЫ рднреА рдирд╣реАрдВ рд▓рд┐рдЦ рдкрд╛рдПрдВрдЧреЗ рдЬреИрд╕реЗ рдХрд┐ f(x: A = B()) ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рдЯреНрд░рд┐рдХ рд╡реИрд░рд┐рдПрдмрд▓ рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреА рд╣реИ: a: A = None рддреНрд░реБрдЯрд┐ a: A = None рдХрд░реЗрдЧрд╛ред

 def f(x: int = None): reveal_type(x) def g(y: int = 'x'): reveal_type(y) z: int = None reveal_type(z) $ mypy test.py test.py:2: error: Revealed type is 'Union[builtins.int, None]' test.py:4: error: Incompatible default for argument "y" (default has type "str", argument has type "int") test.py:5: error: Revealed type is 'builtins.int' test.py:7: error: Incompatible types in assignment (expression has type "None", variable has type "int") test.py:8: error: Revealed type is 'builtins.int' 

***

рдкрд╛рдпрдерди 3 рдореЗрдВ, рдЬрдм рдПрдХ except рдПрдХ рдмреНрд▓реЙрдХ рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рддреЗ рд╣реИрдВ, рддреЛ рдкрдХрдбрд╝реЗ рдЧрдП рдЪрд░ рдХреЛ locals() рд╕реЗ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ locals() , рднрд▓реЗ рд╣реА рд╡реЗ рдореМрдЬреВрдж рд╣реЛрдВ:

 >>> e = 2 >>> try: ... 1/0 ... except Exception as e: ... pass ... >>> e Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'e' is not defined 

рдпрджрд┐ рдЖрдк рд▓рд┐рдВрдХ рдХреЛ рдЕрдкрд╡рд╛рдж рдореЗрдВ рд░рдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рджреВрд╕рд░реЗ рдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

 >>> error = None >>> try: ... 1/0 ... except Exception as e: ... error = e ... >>> error ZeroDivisionError('division by zero',) 

рдЕрдЬрдЧрд░ 2 рдореЗрдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдРрд╕рд╛ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред




рдЖрдк рдЖрд╕рд╛рдиреА рд╕реЗ рдЕрдкрдиреА рдЦреБрдж рдХреА рдкрд┐рдкреА рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдЖрдкрдХреЛ рдЕрдкрдиреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рдЕрдВрджрд░ рдкреИрдХреЗрдЬ рдЬрд╛рд░реА рдХрд░рдиреЗ рдФрд░ рдЙрдиреНрд╣реЗрдВ pip рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдЬреИрд╕реЗ рдХрд┐ рд╡реЗ рдирд┐рдпрдорд┐рдд рдкреИрдХреЗрдЬ рдереЗред

рдпрд╣ рдзреНрдпрд╛рди рд░рдЦрдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рд╕реЙрдлрд╝реНрдЯрд╡реЗрдпрд░ рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдЖрдк рдирд┐рдпрдорд┐рдд HTTP рд╕рд░реНрд╡рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕ рддрд░рд╣ рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рдЖрджрд┐рдо pythonetc рдкреИрдХреЗрдЬ рд▓реЗрдВред

 setup.py: from setuptools import setup, find_packages setup( name='pythonetc', version='1.0', packages=find_packages(), ) pythonetc.py: def ping(): return 'pong' 

рдЪрд▓рд┐рдП рдЗрд╕реЗ ~/pypi рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рдЬрд╛рд░реА рдХрд░рддреЗ рд╣реИрдВ:

 $ python setup.py sdist bdist_wheel тАж $ mv dist ~/pypi/pythonetc 

рдФрд░ рд╣рдо nginx рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ pypi.pushtaev.ru рдбреЛрдореЗрди рд╕реЗ рдкреИрдХреЗрдЬ рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░реЗрдВрдЧреЗ:

 $ cat /etc/nginx/sites-enabled/pypi server { listen 80; server_name pypi.pushtaev.ru; root /home/vadim/pypi; index index.html index.htm index.nginx-debian.html; location / { autoindex on; try_files $uri $uri/ =404; } } 

рдЕрдм рдкреИрдХреЗрдЬ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

 $ pip install -i http://pypi.pushtaev.ru --trusted-host pypi.pushtaev.ru pythonetc тАж Collecting pythonetc Downloading http://pypi.pushtaev.ru/pythonetc/pythonetc-1.0-py3-none-any.whl Installing collected packages: pythonetc Successfully installed pythonetc-1.0 $ python Python 3.7.0+ (heads/3.7:0964aac, Mar 29 2019, 00:40:55) [GCC 4.9.2] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import pythonetc >>> pythonetc.ping() 'pong' 





рдЕрдХреНрд╕рд░ рдЖрдкрдХреЛ рд╕реНрдерд╛рдиреАрдп рдЪрд░ рдХреЗ рд╕рдорд╛рди рдирд╛рдо рдХреА рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╢рдмреНрджрдХреЛрд╢ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

 dict( context=context, mode=mode, action_type=action_type, ) 

рдРрд╕реЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдИрд╕реАрдПрдордПрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рднреА object рд╢рд╛рдмреНрджрд┐рдХ рдХрд╛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╣реЛрддрд╛ рд╣реИ (рдЬрд┐рд╕реЗ рд╡рд╕реНрддреБ рд╢рд╛рдмреНрджрд┐рдХ рд╕рдВрдкрддреНрддрд┐ рдореВрд▓реНрдп рдЖрд╢реБрд▓рд┐рдкрд┐ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ):

 > var a = 1; < undefined > var b = 2; < undefined > {a, b} < {a: 1, b: 2} 

рдЖрдк рдкрд╛рдпрдерди рдореЗрдВ рдПрдХ рд╣реА рд╕рд╣рд╛рдпрдХ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ (рдЕрдлрд╕реЛрд╕, рдпрд╣ рд╕рдм рдИрд╕реАрдПрдорд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдЕрдВрдХрди рдХреЗ рд░реВрдк рдореЗрдВ рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рд╣реИ:

 def shorthand_dict(lcls, names): return {k: lcls[k] for k in names} context = dict(user_id=42, user_ip='1.2.3.4') mode = 'force' action_type = 7 shorthand_dict(locals(), [ 'context', 'mode', 'action_type', ]) 

рдЖрдк рдкреВрдЫ рд╕рдХрддреЗ рд╣реИрдВ, рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ locals() рдХреЛ рдХреНрдпреЛрдВ рдкрд╛рд╕ рдХрд░реЗрдВ? рдХреНрдпрд╛ рдХреЙрд▓рд┐рдВрдЧ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ locals рдХреЙрд▓ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ? рдЖрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ inspect рдореЙрдбреНрдпреВрд▓ inspect рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛:

 import inspect def shorthand_dict(names): lcls = inspect.currentframe().f_back.f_locals return {k: lcls[k] for k in names} context = dict(user_id=42, user_ip='1.2.3.4') mode = 'force' action_type = 7 shorthand_dict([ 'context', 'mode', 'action_type', ]) 

рдЖрдк рдФрд░ рднреА рдЖрдЧреЗ рдмрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕ рддрд░рд╣ рдХрд╛ рд╕рдорд╛рдзрд╛рди рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - https://github.com/alexmojaki/sorcery :

 from sorcery import dict_of dict_of(context, mode, action_type) 

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


All Articles