ä»ã©ãã® Python ãªãããã©ã«ã弿°ã«ç©ºã® list ã dict ãæå®ãã¦ãè¯ããªãï¼
ãã®è¨äºã¯Python Advent Calendar 2020 ã®ï¼æ¥ç®ã®è¨äºã§ãã
ä»å¹´ã® PyConJP 2020 ã§ã¯ãPython ã®åãã³ãã«ã¤ãã¦ç»å£ããã¦ããã ãã¾ããã
2020 å¹´ãçµããããã§ããããããã 2021 å¹´ãã㯠Python ã®ããã©ã«ã弿°ã« list å ¥ãã¦ããããªããï¼ãã¨ããææ¡ããã¦ã¿ããã¨æãã¾ãã
Python ã®ããã©ã«ã弿°ã®ã¢ã³ããã¿ã¼ã³
Python ã¯å¼æ°ã«ããã©ã«ãå¤(ããã©ã«ã弿°)ãæå®ãããã¨ãã§ãã¾ãã
def generate_zero(x=0): return x zero = generate_zero() print(zero) # 0 print(zero + 1) # 1 print(generate_zero()) # 0
å½ããåã®ããã«ãããã©ã«ã弿°ã«æå®ãã 0
ã¨ããæ°åã使ããã¦ãã¾ããgenerate_zero ã®è¿ãå¤ã¯å¸¸ã« 0 ã§ããå½ããåã§ããã
ããããããã©ã«ã弿°ã« list
ã dict
ã®ãããªãã¥ã¼ã¿ãã«ãªãã¼ã¿æ§é ãå
¥ããã¨ãããããªãã¨ã«ãªã£ã¦ãã¾ãã
def generate_empty_list(x=[]): return x list1 = generate_empty_list() print(list1) # [] list1.append('append') print(list1) # ['append'] list2 = generate_empty_list() print(list2) # [] ã§ã¯ãªã ['append'] ã«ãªã
generate_empty_list
ãè¿ã list1
㨠list2
ã¯ãåãã¤ã³ã¹ã¿ã³ã¹ãåç
§ãã¦ãã¾ãããã®ãããããã©ã«ã弿°ã«ç©ºã®ãªã¹ãçãå
¥ãã¦åæå¤ã¨ãã¦ãã¾ãã¨ããã®å¤ã«å¾ããç ´å£çãªå¤æ´ãå ããã¨ãã«ãåæå¤ã®å¤ãæ¸ãæãã£ã¦ãã¾ãã®ã§ãï¼
ãã®æåã¯ãä¾ãã° TypeScript ãªã©ã¨ã¯ç°ãªãã¾ãã
function generate_empty_list(x=[]): string[] { return x } const list1 = generate_empty_list() console.log(list1) // [] list1.push('append') console.log(list1) // ['append'] const list2 = generate_empty_list() console.log(list2) // []
ãã®æåãããããã«ãPython ã®ããã©ã«ã弿°ã«ã¯ã空㮠list ã dict ãªã©ã®ãã¥ã¼ã¿ãã«ãªæ§é ãå ¥ããã¹ãã§ãªã ã¨ãã£ããã©ã¯ãã£ã¹ãæå±ããã¦ãã¾ã*1ãçµæã¨ãã¦ãPython ã§ã®å®å ¨ãªããã°ã©ã ã¯æ¬¡ã®ããã«ãªãã¾ãã
def generate_empty_list(x=None): if x is None: return [] return x
ä»è¨èªå¦ç¿è ã«ã¨ã£ã¦ããã®ä»æ§ã¯åé·ã¨ããããç´æçã§ã¯ãªãæãããã¾ããå®éããã°ãã° Python ã®ãããã©ããã¨ãã¦ç´¹ä»ããã¦ãã¾ããããã§ä»æ¥ã¯ãã®ãã©ã¯ãã£ã¹ã«ç°è«ãæèµ·ãã¦ã¿ã¾ãã
æ°ãããã©ã¯ãã£ã¹
ææ¡ããããã©ã¯ãã£ã¹ã¯ ã¤ãã¥ã¼ã¿ãã«ãªåãã³ããã¤ããã ã§ãã
ããã©ã«ã弿°ã®å¤ãæ¸ãæãã£ã¦ãã¾ãçç±ã¯ãå³å¯ã«ã¯ããã¥ã¼ã¿ãã«ãªãã®ãæå®ãããããã§ã¯ãªããç ´å£ç夿´ãå ãããããã§ãããããã£ã¦ç ´å£ç夿´ããå ããªããã°ãä»åã®åé¡ã¯çºçãã¾ãããPython ã§ã¯ 3.5 ããåãã³ãã¨ããæ©è½ãæä¾ããã¦ãããmypy ãªã©ã®åãã§ãã«ã¼ã§æ¤æ»ãããã¨ãã§ãã¾ããç ´å£ç夿´ãå ãããã¨ã«ã§ããªããappend ã®ãªã list ãä½ã£ã¦ãã¾ãã°ãããã©ã«ã弿°ã®åé¡ã¯è§£æ¶ãã¾ãã
ã¡ããã© Python ã§ã¯ãã¤ãã¥ã¼ã¿ãã«ãª listãããã¤ãã¥ã¼ã¿ãã«ãª dictãã®ãããªåãæä¾ããã¦ãããã³ã¬ã¯ã·ã§ã³æ½è±¡åºåºã¯ã©ã¹ã¨ãã¦æä¾ããã¦ãã¾ããä¾ãã° Sequence
ã¯å®è³ªã¤ãã¥ã¼ã¿ãã«ãª list ã§ãMapping
ã¯å®è³ªã¤ãã¥ã¼ã¿ãã«ãª dict ã«ãªã£ã¦ãã¾ããããã¯æ½è±¡ã¯ã©ã¹ã®ããã±ã¼ã¸ã§ã¯ããã¾ãããåãã§ãã«ã¼ä¸ã§ã¯ Protocol ã®ãããªæ¯ãèãããããããã¾ãã *2
å®éã®ä¾ãè¦ã¦ã¿ã¾ãããã
from collections.abc import Sequence immutable_list: Sequence = [] immutable_list.append('append') # ***.py:4: error: "Sequence[Any]" has no attribute "append" # Found 1 error in 1 file (checked 1 source file)
ãã®ä¾ã¯ mypy ã§ãã§ãã¯ãããã¨ã¨ã©ã¼ãåãã¾ãããªããã¨ããã¨ã immutable_list
ã®å¤æ°ã¯ Sequence
åã§ããã append ãªã©ã®ç ´å£çãªã¡ã½ãããæããªãããã§ãã
ããã䏿¹ã§ãèªã¿è¾¼ã¿å°ç¨ã® list ã®æ¯ãèãã¯åé¡ãªãæã£ã¦ãã¾ããã¾ããProtocol ã®ãããªæ¯ãèããªã®ã§ãSequence ããã®ç¶æ¿ããã¤ã³ã¹ã¿ã³ã¹ãã®ãã®ãä»£å ¥ããå¿ è¦ã¯ããã¾ããã
from collections.abc import Sequence immutable_list: Sequence = [] print([x for x in immutable_list]) # OK print('element' in immutable_list) # OK # Success: no issues found in 1 source file
ããã§ã¯ãå½åã®åé¡ã§ãã£ããããã©ã«ã弿°ã« list / dict å ¥ããåé¡ãã«ã¤ãã¦ããã¤ãã¥ã¼ã¿ãã«ãªåãã³ããã¤ããããã¨ãããã©ã¯ãã£ã¹ãé©ç¨ãã¦ã¿ã¾ãã
from collections.abc import Sequence def generate_empty_list(x=[]) -> Sequence: return x list = generate_empty_list() print(list) list.append('append') # error: "Sequence[Any]" has no attribute "append" print(list) list2 = generate_empty_list() print(list2)
ãã®ããã«æ»ãå¤ã弿°ã«åãã³ããã¤ãã¦ãããã¨ãmypy ããappend ã§ããªãããã¨æ³¨æãã¦ããã¾ãããããã¦ãããã©ã«ã弿°ãå¤ãã£ã¡ããåé¡ã¯è§£æ¶ããã¾ããããã§ãããã§ãã
ã¡ãªããã¨ãã¡ãªãã
ã¡ãªããã¨ãã¦ã¯ãè¦éããé常ã«ãã£ããããã®ã§ã¯ãªããã¨æãã¾ããTypeScript åæ§ãããã©ã«ã弿°ã« list ãå ¥ãã¦è¯ãã®ã§ãä»è¨èªå¦ç¿è ã«ã¨ã£ã¦ç´æçããããã¾ãããå人çãªæè¦ã¨ãã¦ãPython ã¯æããã«åãã³ãã®ããã¼ã»å½¹å²ãåºãããã¨ãã¦ããã®ã§ãããã¯å°æ¥ "Pythonic" ãªæ¸ãæ¹ã¨ãããããããã¾ããã
ã¨ãææ¡ãã¦ã¿ããã®ã®ã ãã¡ãªããã大ãã ã¨æã£ã¦ã¾ããããã¯ã©ã³ã¿ã¤ã ã¬ãã«ã§ã®ãã§ãã¯ã§ã¯ããã¾ããããªã®ã§ãmypy çã«ããåãã§ãã¯ãè¡ããã¨ããã®åæ¨è«ãæ£ããåããã¨ãä¸å¯æ¬ ã§ããmypy ã®ç²¾åº¦ã¯ãä¾ãã° TypeScript ãªã©ã¨æ¯ã¹ã¦ãããã»ã©é«ããªããã¨ããã®ã¯æ£ç´ãªææ³ã§ã(2020å¹´ã®ææ³ã§ã)ã
çµããã«
æ¬ç¨¿ã§ã¯ãããã©ã«ã弿°ã«ãã¥ã¼ã¿ãã«ãªãã®ãå ¥ãã¦ã¯ãããªããã¨ãããã©ã¯ãã£ã¹ã«å¯¾ãã¦ãåãã³ãã«ãã解決çãæç¤ºãã¾ãããç»å£å 容ã®ã¯ã¦ãã®ã³ã¡ã³ããèããããã«ãåçåä»ãè¨èªã«åãæã¡è¾¼ããã¨ãã«å¯¾ãã¦ã¯ãæ§ã ãªæè¦ããããã¨æãã¾ãã
åå人ã¨ãã¦ã¯ãPython ã®åå¨ãã®ã¨ã³ã·ã¹ãã ãé²åããããã«ä½¿ããããã¦å®å ¨ãªè¨èªã¨ãªããã¨ãé¡ã£ã¦ãã¿ã¾ãããGuido ããã Microsoft å ¥ã£ããï¼
*1:ãPython ããã©ã«ã弿° ãã¥ã¼ã¿ãã«ãã§ã°ã°ãã¨è¨äºãããã£ã±ããã§ã¦ãã¾ã
*2:ã©ã³ã¿ã¤ã ä¸ã§ã¯ list ã ããåãã§ãã¯ã®ä¸ã§ã¯ append ã __setitem__ ãªã©ãæããªã