[{"data":1,"prerenderedAt":991},["ShallowReactive",2],{"content-\u002Fcontents\u002Fpython":3,"surroundPost-\u002Fcontents\u002Fpython":982},{"id":4,"title":5,"body":6,"createdAt":970,"description":971,"draft":972,"extension":973,"meta":974,"navigation":149,"path":975,"seo":976,"stem":977,"tags":978,"thumbnail":980,"updatedAt":970,"__hash__":981},"contents\u002Fcontents\u002Fpython.md","意外と知らなかったPythonの便利な書き方集",{"type":7,"value":8,"toc":959},"minimark",[9,26,29,32,35,74,79,82,87,90,96,109,114,122,127,192,195,198,201,204,219,222,225,229,247,251,271,275,278,306,316,327,332,356,359,368,374,384,389,428,432,435,439,447,451,456,460,463,512,515,519,522,525,528,531,534,538,553,557,565,569,576,616,619,628,635,638,677,684,727,730,733,739,743,770,774,779,783,792,851,860,894,897,900,903,906,955],[10,11,12,19,20,25],"p",{},[13,14,18],"a",{"href":15,"rel":16},"https:\u002F\u002Famzn.to\u002F3CnNIIY",[17],"nofollow","エキスパート Python プログラミング改訂 3 版","を読んだので個人的に新たに使えそうと思ったことをまとめます。\nプラスで",[13,21,24],{"href":22,"rel":23},"https:\u002F\u002Famzn.to\u002F3pDVn2f",[17],"自走プログラマー","で学んだことも含めておきます。",[10,27,28],{},"2 冊とも業務で Python を使う身としてはめちゃめちゃ勉強になる本だったのでおすすめです。",[10,30,31],{},"使用する Python バージョンは本家と同じく Python 3.9 にします。",[10,33,34],{},"環境は Docker ではなく pyenv と venv で構築しました。",[36,37,42],"pre",{"className":38,"code":39,"language":40,"meta":41,"style":41},"language-bash shiki shiki-themes github-dark","python -m venv .venv\nsource .venv\u002Fbin\u002Factivate\n","bash","",[43,44,45,65],"code",{"__ignoreMap":41},[46,47,50,54,58,62],"span",{"class":48,"line":49},"line",1,[46,51,53],{"class":52},"svObZ","python",[46,55,57],{"class":56},"sDLfK"," -m",[46,59,61],{"class":60},"sU2Wk"," venv",[46,63,64],{"class":60}," .venv\n",[46,66,68,71],{"class":48,"line":67},2,[46,69,70],{"class":56},"source",[46,72,73],{"class":60}," .venv\u002Fbin\u002Factivate\n",[75,76,78],"h2",{"id":77},"python-便利な書き方集","Python 便利な書き方集",[10,80,81],{},"自分がよく使う、または使えそうと思ったこと中心です。\n有名どころな書き方もちらほらありますが、普段使う時も結構ググったりしてるのでこの機会にまとめます。",[83,84,86],"h3",{"id":85},"リスト内包表記辞書内包表記","リスト内包表記・辞書内包表記",[10,88,89],{},"まずはリスト内包表記から紹介します。\nC 言語などの for 文に慣れてるとちょっと初見ではとっつきにくいですが、慣れてくるとコードの記述量も減り、綺麗になるので便利です。",[10,91,92],{},[93,94,95],"strong",{},"どんなもの？",[97,98,99,103,106],"ul",{},[100,101,102],"li",{},"iterable な要素を使ってリストを作る書き方",[100,104,105],{},"普通に for 文と append などを使って書くよりも綺麗にかける",[100,107,108],{},"条件式もかけるので汎用性が高い",[10,110,111],{},[93,112,113],{},"使いどころ",[97,115,116,119],{},[100,117,118],{},"あるリストの要素を別のリストに変換する時などに使う",[100,120,121],{},"具体的には glob でリスト化したパスをある規則で抽出したいときなどに使える",[10,123,124],{},[93,125,126],{},"具体例",[36,128,132],{"className":129,"code":130,"language":131,"meta":41,"style":41},"language-py shiki shiki-themes github-dark","numbers = list(range(0,10))\n# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n\n# 2倍にする\ntwice = [i * 2 for i in numbers]\n# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]\n\n# if文バージョン\neven = [i for i in numbers if i % 2 == 0]\n# [0, 2, 4, 6, 8]\n","py",[43,133,134,139,144,151,157,163,169,174,180,186],{"__ignoreMap":41},[46,135,136],{"class":48,"line":49},[46,137,138],{},"numbers = list(range(0,10))\n",[46,140,141],{"class":48,"line":67},[46,142,143],{},"# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n",[46,145,147],{"class":48,"line":146},3,[46,148,150],{"emptyLinePlaceholder":149},true,"\n",[46,152,154],{"class":48,"line":153},4,[46,155,156],{},"# 2倍にする\n",[46,158,160],{"class":48,"line":159},5,[46,161,162],{},"twice = [i * 2 for i in numbers]\n",[46,164,166],{"class":48,"line":165},6,[46,167,168],{},"# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]\n",[46,170,172],{"class":48,"line":171},7,[46,173,150],{"emptyLinePlaceholder":149},[46,175,177],{"class":48,"line":176},8,[46,178,179],{},"# if文バージョン\n",[46,181,183],{"class":48,"line":182},9,[46,184,185],{},"even = [i for i in numbers if i % 2 == 0]\n",[46,187,189],{"class":48,"line":188},10,[46,190,191],{},"# [0, 2, 4, 6, 8]\n",[10,193,194],{},"if 文を使う場合は、if の条件式が後ろに着くのがポイント。",[10,196,197],{},"続いて辞書内包表記です。",[10,199,200],{},"基本的にはリスト内包表記と同じです。違いとしては、キーと値それぞれ処理する点がリスト内包表記と異なります。",[10,202,203],{},"具体例は以下です。",[36,205,207],{"className":129,"code":206,"language":131,"meta":41,"style":41},"even_squares = {num: num**2 for num in range(10) if num % 2 == 0}\n# {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}\n",[43,208,209,214],{"__ignoreMap":41},[46,210,211],{"class":48,"line":49},[46,212,213],{},"even_squares = {num: num**2 for num in range(10) if num % 2 == 0}\n",[46,215,216],{"class":48,"line":67},[46,217,218],{},"# {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}\n",[83,220,221],{"id":221},"ラムダ関数",[10,223,224],{},"続いてラムダ関数です。無名関数などと呼ばれたりするものです。",[10,226,227],{},[93,228,95],{},[97,230,231,237,244],{},[100,232,233,236],{},[43,234,235],{},"lanbda \u003C引数>: \u003C式>","の形で記述",[100,238,239,240,243],{},"通常、関数は",[43,241,242],{},"def \u003C関数名>:","のように定義して使うが、ラムダ関数は上記のような記述で書ける",[100,245,246],{},"簡単な関数かつ、他で再利用されないものならばラムダ関数の方が簡潔にかけて綺麗",[10,248,249],{},[93,250,113],{},[97,252,253,264],{},[100,254,255,256,259,260,263],{},"後述する",[43,257,258],{},"map","や",[43,261,262],{},"filter","と組み合わせることでちょっと複雑なデータ変換やデータ抽出を簡潔に書ける",[100,265,266,267,270],{},"関数を引数にとるもの（組み込み関数の",[43,268,269],{},"max","など）がたまにあるのでそれらに対する引数として渡す",[10,272,273],{},[93,274,126],{},[10,276,277],{},"リストの全ての要素の空白文字を_に変換します。",[36,279,281],{"className":129,"code":280,"language":131,"meta":41,"style":41},"names = [\"taro sato\", \"yuki tanaka\", \"hanako yamada\"]\n\nreplaced_names = list(map(lambda x: x.replace(\" \", \"_\"), names))\n\n# ['taro_sato', 'yuki_tanaka', 'hanako_yamada']\n",[43,282,283,288,292,297,301],{"__ignoreMap":41},[46,284,285],{"class":48,"line":49},[46,286,287],{},"names = [\"taro sato\", \"yuki tanaka\", \"hanako yamada\"]\n",[46,289,290],{"class":48,"line":67},[46,291,150],{"emptyLinePlaceholder":149},[46,293,294],{"class":48,"line":146},[46,295,296],{},"replaced_names = list(map(lambda x: x.replace(\" \", \"_\"), names))\n",[46,298,299],{"class":48,"line":153},[46,300,150],{"emptyLinePlaceholder":149},[46,302,303],{"class":48,"line":159},[46,304,305],{},"# ['taro_sato', 'yuki_tanaka', 'hanako_yamada']\n",[10,307,308,309,311,312,315],{},"ここで出てきた",[43,310,258],{},"は組み込み関数であり、iterable の各要素に対して関数を適用します。\n使い方は",[43,313,314],{},"map(\u003C関数>, \u003Citerable>)","のように使います。",[10,317,318,320,321,323,324,326],{},[43,319,258],{},"とよく一緒に出てくるものに",[43,322,262],{},"があります。\nこちらは",[43,325,258],{},"と異なり、適用した関数にマッチしたものだけ返します。",[10,328,329,331],{},[43,330,262],{},"を使って同じ苗字だけ抽出してみます。",[36,333,335],{"className":129,"code":334,"language":131,"meta":41,"style":41},"names = [\"taro sato\", \"yuki tanaka\",\"yuriko sato\",\"hanako yamada\"]\n\nsatos = list(filter(lambda x: \"sato\" in x, names))\n# ['taro sato', 'yuriko sato']\n",[43,336,337,342,346,351],{"__ignoreMap":41},[46,338,339],{"class":48,"line":49},[46,340,341],{},"names = [\"taro sato\", \"yuki tanaka\",\"yuriko sato\",\"hanako yamada\"]\n",[46,343,344],{"class":48,"line":67},[46,345,150],{"emptyLinePlaceholder":149},[46,347,348],{"class":48,"line":146},[46,349,350],{},"satos = list(filter(lambda x: \"sato\" in x, names))\n",[46,352,353],{"class":48,"line":153},[46,354,355],{},"# ['taro sato', 'yuriko sato']\n",[10,357,358],{},"ちなみに上記の例はリスト内包表記で書くと以下のようになります。",[36,360,362],{"className":129,"code":361,"language":131,"meta":41,"style":41},"replaced_names = [x.replace(\" \", \"_\") for x in names]\n",[43,363,364],{"__ignoreMap":41},[46,365,366],{"class":48,"line":49},[46,367,361],{},[10,369,370,371,373],{},"この例だとリスト内包表記と差別化できないので前述した組み込み関数",[43,372,269],{},"の例を紹介します。",[10,375,376,378,379,383],{},[43,377,269],{},"はその名の通り、iterable な要素から最大のものを返してくれます。（参考：",[13,380,269],{"href":381,"rel":382},"https:\u002F\u002Fdocs.python.org\u002Fja\u002F3\u002Flibrary\u002Ffunctions.html#max",[17],"）",[10,385,386,388],{},[43,387,269],{},"の引数にはタプルのリストも渡すことができます。例えばタプルの 2 番目の要素だけ評価対象にしたい場合はラムダ関数を使って以下のように書けます。",[36,390,392],{"className":129,"code":391,"language":131,"meta":41,"style":41},"# (name, age)のリスト\nperson = [(\"taro sato\", 10), (\"yuki tanaka\", 32), (\"hanako yamada\", 24)]\n\n# リスト中でageが最大な要素を抽出したい\n# lambda関数でタプルの位置を指定している\nmax_age = max(person, key=lambda x: x[1])\n#('yuki tanaka', 32)\n",[43,393,394,399,404,408,413,418,423],{"__ignoreMap":41},[46,395,396],{"class":48,"line":49},[46,397,398],{},"# (name, age)のリスト\n",[46,400,401],{"class":48,"line":67},[46,402,403],{},"person = [(\"taro sato\", 10), (\"yuki tanaka\", 32), (\"hanako yamada\", 24)]\n",[46,405,406],{"class":48,"line":146},[46,407,150],{"emptyLinePlaceholder":149},[46,409,410],{"class":48,"line":153},[46,411,412],{},"# リスト中でageが最大な要素を抽出したい\n",[46,414,415],{"class":48,"line":159},[46,416,417],{},"# lambda関数でタプルの位置を指定している\n",[46,419,420],{"class":48,"line":165},[46,421,422],{},"max_age = max(person, key=lambda x: x[1])\n",[46,424,425],{"class":48,"line":171},[46,426,427],{},"#('yuki tanaka', 32)\n",[83,429,431],{"id":430},"forelse-正常終了時の処理","for...else 正常終了時の処理",[10,433,434],{},"続いて割と使いどころが多そうだと思った for..else の書き方を紹介します。",[10,436,437],{},[93,438,95],{},[97,440,441,444],{},[100,442,443],{},"for 文が break されずに正常に終了した場合の処理を書ける",[100,445,446],{},"break したかどうかのフラグのような変数が必要なくなる",[10,448,449],{},[93,450,113],{},[97,452,453],{},[100,454,455],{},"break した場合としてない場合で違う処理を行いたいときに使う",[10,457,458],{},[93,459,126],{},[10,461,462],{},"あまりいい例ではないかもですが、以下のように使います。\nこの方法の欠点として、パッと見 if 文と対になってる else に見えてしまうことです。",[36,464,466],{"className":129,"code":465,"language":131,"meta":41,"style":41},"names = [\"taro sato\", \"yuki tanaka\",\"yuriko sato\",\"hanako yamada\"]\n#query = \"takashi saito\"\nquery = \"taro sato\"\nfor idx, name in enumerate(names):\n    if name == query:\n        print(f\"{name} is included in names\")\n        break\nelse:\n    print(\"takashi saito is not included in names\")\n",[43,467,468,472,477,482,487,492,497,502,507],{"__ignoreMap":41},[46,469,470],{"class":48,"line":49},[46,471,341],{},[46,473,474],{"class":48,"line":67},[46,475,476],{},"#query = \"takashi saito\"\n",[46,478,479],{"class":48,"line":146},[46,480,481],{},"query = \"taro sato\"\n",[46,483,484],{"class":48,"line":153},[46,485,486],{},"for idx, name in enumerate(names):\n",[46,488,489],{"class":48,"line":159},[46,490,491],{},"    if name == query:\n",[46,493,494],{"class":48,"line":165},[46,495,496],{},"        print(f\"{name} is included in names\")\n",[46,498,499],{"class":48,"line":171},[46,500,501],{},"        break\n",[46,503,504],{"class":48,"line":176},[46,505,506],{},"else:\n",[46,508,509],{"class":48,"line":182},[46,510,511],{},"    print(\"takashi saito is not included in names\")\n",[10,513,514],{},"for...else を使わない場合、print 文の出力を分けるには idx と len(names)を比較する if 文などが必要になります。",[75,516,518],{"id":517},"アプリケーション開発で使えそうな-python-の書き方集","アプリケーション開発で使えそうな Python の書き方集",[10,520,521],{},"機械学習やちょっとしたコードを試す場合と、アプリケーションとして Python を書く場合は、若干気になるところが違います。\nアプリケーションの場合は複数人で開発することや長期でメンテナンスすることを想定し、可読性や間違った使い方ができないようにすることも大事です。",[10,523,524],{},"ということで、ここではアプリケーション開発に役立ちそうな書き方をまとめます。",[83,526,527],{"id":527},"キーワードのみ引数",[10,529,530],{},"Python では関数を呼ぶ際に引数名を省略して関数を呼び出すことができます。\nそれはそれで便利なのですが、複雑な関数だったり、関数の意図が分かりづらい場合など、後から見たときに引数の役割が分からなくなることがあります。",[10,532,533],{},"そんな時に便利なのがキーワードのみ引数です。",[10,535,536],{},[93,537,95],{},[97,539,540,543],{},[100,541,542],{},"デフォルト引数を持つ関数呼び出しの際に引数名の記述を強制できる",[100,544,545,546,549,550,552],{},"キーワード指定のみで使いたい引数の前に",[43,547,548],{},"*","を書く。",[43,551,548],{},"以降の引数はキーワード指定でしか使えなくなる",[10,554,555],{},[93,556,113],{},[97,558,559,562],{},[100,560,561],{},"bool 値など引数の値だけじゃ中の動作を推測しづらい時に使える",[100,563,564],{},"場合によってはチームでルール化するとかもありかも",[10,566,567],{},[93,568,126],{},[10,570,571,572,575],{},"例えば以下のような デフォルト引数",[43,573,574],{},"admin=True"," ならリストから情報を持ってくる関数があるとします。",[36,577,579],{"className":129,"code":578,"language":131,"meta":41,"style":41},"def get_personal_info(name, age, gender, admin=True):\n    # (name, age, gender)のリスト\n    people = [(\"taro sato\", 10, \"man\"), (\"yuki tanaka\", 32, \"man\"), (\"yuriko sato\", 60, \"woman\"), (\"hanako yamada\", 24,\"woman\")]\n    if admin:\n        target_info = list(filter(lambda x: name==x[0] and age==x[1] and gender==x[2] in x, people))\n        return target_info\n    return [()]\n",[43,580,581,586,591,596,601,606,611],{"__ignoreMap":41},[46,582,583],{"class":48,"line":49},[46,584,585],{},"def get_personal_info(name, age, gender, admin=True):\n",[46,587,588],{"class":48,"line":67},[46,589,590],{},"    # (name, age, gender)のリスト\n",[46,592,593],{"class":48,"line":146},[46,594,595],{},"    people = [(\"taro sato\", 10, \"man\"), (\"yuki tanaka\", 32, \"man\"), (\"yuriko sato\", 60, \"woman\"), (\"hanako yamada\", 24,\"woman\")]\n",[46,597,598],{"class":48,"line":153},[46,599,600],{},"    if admin:\n",[46,602,603],{"class":48,"line":159},[46,604,605],{},"        target_info = list(filter(lambda x: name==x[0] and age==x[1] and gender==x[2] in x, people))\n",[46,607,608],{"class":48,"line":165},[46,609,610],{},"        return target_info\n",[46,612,613],{"class":48,"line":171},[46,614,615],{},"    return [()]\n",[10,617,618],{},"この関数は以下のように使えます。",[36,620,622],{"className":129,"code":621,"language":131,"meta":41,"style":41},"get_personal_info(\"taro sato\", 10, \"man\", True)\n",[43,623,624],{"__ignoreMap":41},[46,625,626],{"class":48,"line":49},[46,627,621],{},[10,629,630,631,634],{},"これを見ると先ほど述べた問題点がわかると思います。最後の引数の",[43,632,633],{},"True","が何を意味しているのかわかりません。",[10,636,637],{},"続いて、キーワード引数を用いて関数を定義してみます。",[36,639,641],{"className":129,"code":640,"language":131,"meta":41,"style":41},"# キーワードのみの引数を指定\ndef get_personal_info(name, age, gender, *, admin=True):\n    # (name, age, gender)のリスト\n    people = [(\"taro sato\", 10, \"man\"), (\"yuki tanaka\", 32, \"man\"), (\"yuriko sato\", 60, \"woman\"), (\"hanako yamada\", 24,\"woman\")]\n    if admin:\n        target_info = list(filter(lambda x: name==x[0] and age==x[1] and gender==x[2] in x, people))\n        return target_info\n    return [()]\n",[43,642,643,648,653,657,661,665,669,673],{"__ignoreMap":41},[46,644,645],{"class":48,"line":49},[46,646,647],{},"# キーワードのみの引数を指定\n",[46,649,650],{"class":48,"line":67},[46,651,652],{},"def get_personal_info(name, age, gender, *, admin=True):\n",[46,654,655],{"class":48,"line":146},[46,656,590],{},[46,658,659],{"class":48,"line":153},[46,660,595],{},[46,662,663],{"class":48,"line":159},[46,664,600],{},[46,666,667],{"class":48,"line":165},[46,668,605],{},[46,670,671],{"class":48,"line":171},[46,672,610],{},[46,674,675],{"class":48,"line":176},[46,676,615],{},[10,678,679,680,683],{},"この関数の",[43,681,682],{},"admin","引数にに対して値を渡したい場合、以下のようにしか呼び出せません。",[36,685,687],{"className":129,"code":686,"language":131,"meta":41,"style":41},"# admin=Falseのようにキーワードを指定しないとエラーになる\nget_personal_info(\"tar sato\", 10, \"man\", admin=False)\n\n# 新たに引数を渡さない場合はOK\nget_personal_info(\"tar sato\", 10, \"man\")\n\n# 以下はTypeErrorになる\n# get_personal_info(\"taro sato\", 10, \"man\", True)\n",[43,688,689,694,699,703,708,713,717,722],{"__ignoreMap":41},[46,690,691],{"class":48,"line":49},[46,692,693],{},"# admin=Falseのようにキーワードを指定しないとエラーになる\n",[46,695,696],{"class":48,"line":67},[46,697,698],{},"get_personal_info(\"tar sato\", 10, \"man\", admin=False)\n",[46,700,701],{"class":48,"line":146},[46,702,150],{"emptyLinePlaceholder":149},[46,704,705],{"class":48,"line":153},[46,706,707],{},"# 新たに引数を渡さない場合はOK\n",[46,709,710],{"class":48,"line":159},[46,711,712],{},"get_personal_info(\"tar sato\", 10, \"man\")\n",[46,714,715],{"class":48,"line":165},[46,716,150],{"emptyLinePlaceholder":149},[46,718,719],{"class":48,"line":171},[46,720,721],{},"# 以下はTypeErrorになる\n",[46,723,724],{"class":48,"line":176},[46,725,726],{},"# get_personal_info(\"taro sato\", 10, \"man\", True)\n",[83,728,729],{"id":729},"dataclass",[10,731,732],{},"アプリ開発をしているとまとまった情報を辞書やクラスにまとめて次の関数に渡していくという処理が多々あります。",[10,734,735,736,738],{},"そんな時に使えるのこの",[43,737,729],{},"です。",[10,740,741],{},[93,742,95],{},[97,744,745,750,760,767],{},[100,746,747,749],{},[43,748,729],{},"は Python 3.7 から導入された情報をクラスにまとめる際に利用できるデコレータ",[100,751,752,753,756,757,759],{},"通常のクラス定義では",[93,754,755],{},"init","に渡す引数が多くなると記述が結構大変ですが、",[43,758,729],{},"だと短くかける",[100,761,762,763,766],{},"特殊メソッドの",[43,764,765],{},"__repr__()","などのメソッドも自動で作ってくれる",[100,768,769],{},"定義したクラスを immutable にもできる",[10,771,772],{},[93,773,113],{},[97,775,776],{},[100,777,778],{},"データ格納用のクラスを使いたい時",[10,780,781],{},[93,782,126],{},[10,784,785,788,789,791],{},[43,786,787],{},"User","クラスを定義することを考えます。\n",[43,790,729],{},"を使うと以下のようにかけます。",[36,793,795],{"className":129,"code":794,"language":131,"meta":41,"style":41},"from dataclasses import dataclass\n\n@dataclass\nclass User:\n    id: int\n    first_name: str\n    last_name: str\n    age: int\n\n# 通常のクラスと同様に使える\nuser =User(id=0, first_name=\"taro\", last_name=\"tanaka\", age=10)\n",[43,796,797,802,806,811,816,821,826,831,836,840,845],{"__ignoreMap":41},[46,798,799],{"class":48,"line":49},[46,800,801],{},"from dataclasses import dataclass\n",[46,803,804],{"class":48,"line":67},[46,805,150],{"emptyLinePlaceholder":149},[46,807,808],{"class":48,"line":146},[46,809,810],{},"@dataclass\n",[46,812,813],{"class":48,"line":153},[46,814,815],{},"class User:\n",[46,817,818],{"class":48,"line":159},[46,819,820],{},"    id: int\n",[46,822,823],{"class":48,"line":165},[46,824,825],{},"    first_name: str\n",[46,827,828],{"class":48,"line":171},[46,829,830],{},"    last_name: str\n",[46,832,833],{"class":48,"line":176},[46,834,835],{},"    age: int\n",[46,837,838],{"class":48,"line":182},[46,839,150],{"emptyLinePlaceholder":149},[46,841,842],{"class":48,"line":188},[46,843,844],{},"# 通常のクラスと同様に使える\n",[46,846,848],{"class":48,"line":847},11,[46,849,850],{},"user =User(id=0, first_name=\"taro\", last_name=\"tanaka\", age=10)\n",[10,852,853,854,856,857,859],{},"書いてみると分かりますが、圧倒的に",[43,855,729],{},"の方が書きやすいです。\n普通のクラス定義で書くと上記の",[43,858,787],{},"クラスは」以下のようになります。",[36,861,863],{"className":129,"code":862,"language":131,"meta":41,"style":41},"class User:\n    def __init__(self, id:int, first_name:str, last_name:str, age:int) -> None:\n        self.id = id\n        self.first_name = first_name\n        self.last_name = last_name\n        self.age = age\n",[43,864,865,869,874,879,884,889],{"__ignoreMap":41},[46,866,867],{"class":48,"line":49},[46,868,815],{},[46,870,871],{"class":48,"line":67},[46,872,873],{},"    def __init__(self, id:int, first_name:str, last_name:str, age:int) -> None:\n",[46,875,876],{"class":48,"line":146},[46,877,878],{},"        self.id = id\n",[46,880,881],{"class":48,"line":153},[46,882,883],{},"        self.first_name = first_name\n",[46,885,886],{"class":48,"line":159},[46,887,888],{},"        self.last_name = last_name\n",[46,890,891],{"class":48,"line":165},[46,892,893],{},"        self.age = age\n",[10,895,896],{},"なんか長いですよね。self で引数を代入する部分が書くのめんどくさいです。",[10,898,899],{},"関数なども通常のように記述できます。",[10,901,902],{},"そして、さらに便利なのが frozen を True にすることで中の値を変更できなくできます。",[10,904,905],{},"具体的には以下のように書きます。",[36,907,909],{"className":129,"code":908,"language":131,"meta":41,"style":41},"@dataclass(frozen=True) # frozen=Trueにすると値を新たにセットできなくなる\nclass User:\n    id: int\n    first_name: str\n    last_name: str\n    age: int\n\nuser = User(id=0, first_name=\"taro\", last_name=\"tanaka\", age=10)\nuser.age = 10 # エラーになる\n# FrozenInstanceError: cannot assign to field 'age'\n",[43,910,911,916,920,924,928,932,936,940,945,950],{"__ignoreMap":41},[46,912,913],{"class":48,"line":49},[46,914,915],{},"@dataclass(frozen=True) # frozen=Trueにすると値を新たにセットできなくなる\n",[46,917,918],{"class":48,"line":67},[46,919,815],{},[46,921,922],{"class":48,"line":146},[46,923,820],{},[46,925,926],{"class":48,"line":153},[46,927,825],{},[46,929,930],{"class":48,"line":159},[46,931,830],{},[46,933,934],{"class":48,"line":165},[46,935,835],{},[46,937,938],{"class":48,"line":171},[46,939,150],{"emptyLinePlaceholder":149},[46,941,942],{"class":48,"line":176},[46,943,944],{},"user = User(id=0, first_name=\"taro\", last_name=\"tanaka\", age=10)\n",[46,946,947],{"class":48,"line":182},[46,948,949],{},"user.age = 10 # エラーになる\n",[46,951,952],{"class":48,"line":188},[46,953,954],{},"# FrozenInstanceError: cannot assign to field 'age'\n",[956,957,958],"style",{},"html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":41,"searchDepth":67,"depth":67,"links":960},[961,966],{"id":77,"depth":67,"text":78,"children":962},[963,964,965],{"id":85,"depth":146,"text":86},{"id":221,"depth":146,"text":221},{"id":430,"depth":146,"text":431},{"id":517,"depth":67,"text":518,"children":967},[968,969],{"id":527,"depth":146,"text":527},{"id":729,"depth":146,"text":729},"2021-10-20","dataclassやlambda関数などPythonで新たに学んだ書き方を中心にいろいろ自分で試した内容をまとめました。",false,"md",{},"\u002Fcontents\u002Fpython",{"title":5,"description":971},"contents\u002Fpython",[979],"Python","\u002Fimg\u002Ftwitter-card.png","srO8GLF8Pr3cmljEuHBkUR_Rza32wsZEsUO2670qkRQ",[983,987],{"title":984,"path":985,"stem":986,"children":-1},"pytestの基本的な使い方","\u002Fcontents\u002Fpytest","contents\u002Fpytest",{"title":988,"path":989,"stem":990,"children":-1},"Pythonでよく使うものをコピペ用にまとめてみた","\u002Fcontents\u002Fpython-util","contents\u002Fpython-util",1784936718500]