Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
変数に変数を代入したら?
Search
mizzsugar
July 04, 2020
Programming
0
2.5k
変数に変数を代入したら?
mizzsugar
July 04, 2020
Tweet
Share
More Decks by mizzsugar
See All by mizzsugar
SQLModel入門〜クエリと型〜
mizzsugar
1
500
フルリモート向いてないと思っていた私が、なんだかんだ健やかに 1年半フルリモート出来ている話
mizzsugar
0
110
Djangoでのプロジェクトだって型ヒントを運用出来る!
mizzsugar
4
8.2k
「動くものは作れる」の一歩先へ 〜「自走プログラマー」の紹介〜
mizzsugar
0
520
pytestの第一歩 〜「テスト駆動Python」の紹介〜
mizzsugar
3
310
データ分析ツール開発でpoetryを使う選択肢
mizzsugar
1
1.1k
unittest.mockを使ってテストを書こう
mizzsugar
5
6.2k
Djangoのパスワードハッシュアルゴリズムで_PyramidのWebアプリケーション作った.pdf
mizzsugar
0
850
unittest.mockを使ってテストを書こう ~モックオブジェクトを使ってより単体テストの目的に沿ったテストに~
mizzsugar
4
1.9k
Other Decks in Programming
See All in Programming
PHPカンファレンス名古屋2025 タスク分解の試行錯誤〜レビュー負荷を下げるために〜
soichi
1
210
Lottieアニメーションをカスタマイズしてみた
tahia910
0
130
プログラミング言語学習のススメ / why-do-i-learn-programming-language
yashi8484
0
130
CI改善もDatadogとともに
taumu
0
120
GitHub Actions × RAGでコードレビューの検証の結果
sho_000
0
270
GAEログのコスト削減
mot_techtalk
0
120
技術を根付かせる / How to make technology take root
kubode
1
250
Pulsar2 を雰囲気で使ってみよう
anoken
0
240
負債になりにくいCSSをデザイナとつくるには?
fsubal
10
2.4k
個人アプリを2年ぶりにアプデしたから褒めて / I just updated my personal app, praise me!
lovee
0
350
パスキーのすべて ── 導入・UX設計・実装の紹介 / 20250213 パスキー開発者の集い
kuralab
3
790
Amazon Q Developer Proで効率化するAPI開発入門
seike460
PRO
0
110
Featured
See All Featured
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
32
2.1k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
12
960
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.6k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
114
50k
StorybookのUI Testing Handbookを読んだ
zakiyama
28
5.5k
Writing Fast Ruby
sferik
628
61k
Speed Design
sergeychernyshev
27
790
Faster Mobile Websites
deanohume
306
31k
The Cult of Friendly URLs
andyhume
78
6.2k
A Modern Web Designer's Workflow
chriscoyier
693
190k
Embracing the Ebb and Flow
colly
84
4.6k
How to Ace a Technical Interview
jacobian
276
23k
Transcript
変数に変数を代入したら? 〜仕組みを知ってハマらないようになろう〜 2020-07-04 Python Charity Talks in Japan @mizzsugar0425 1
前提 • この発表の対象者は初学者です。 • Pythonで変数に変数を代入した時の仕組みを知り、 安全なプログラムを書けるようになることが目的です。 2
お前、誰よ? • みずきと申します。 • Twitter: @mizzsugar0425 • PythonでWebサービスの開発をしています。(Pyramid, Django, PostgreSQL,
Nuxt.js, Angular …) • コーヒーと自転車とPythonが好きです。 3
クイズ① 〜枠の中に入るものは?〜 >>> name_1 = 'aaa' >>> name_2 = name
>>> name_1.replace('a', 'b') 'bbb' >>> name_1 'aaa' >>> name_2 'aaa' 4
クイズ① の答え >>> name_1 = 'aaa' >>> name_2 = name
>>> name_1.replace('a', 'b') 'bbb' >>> name_1 'aaa' >>> name_2 'aaa' 5
クイズ② 〜枠の中に入るものは?〜 >>> list_1 = [1, 2, 3] >>> list_2
= list_1 >>> list_1.append(4) >>> list_1 [1, 2, 3, 4] >>> list_2 [1, 2, 3, 4] 6
クイズ② の答え >>> list_1 = [1, 2, 3] >>> list_2
= l >>> list_1.append(4) >>> list_1 [1, 2, 3, 4] >>> list_2 [1, 2, 3, 4] 7
何故List型の時は変わってしまったのでしょうか? 8
値が変わってしまった理由は オブジェクトの仕組みにあります。 9
Pythonでは全てオブジェクト Pythonでは、int型 str型 List型 … 全てをオブジェクトとして扱います。 10 https://docs.python.org/ja/3/reference/datamodel.html#objects-values-and-types
number = 1 # int型のオブジェクト name = 'Taro' # str型のオブジェクト
names = ['Taro', 'Jiro', 'Saburo'] # List型のオブジェクト class Person: def __init__(self, name: str, age: int) -> None: self.name = name self.age = age person = Person(name='Taro', age=10) # Person型のオブジェクト 11
オブジェクトの識別値を返すid() • 組み込み関数id()はオブジェクトの識別値(identify)を返します。 • id()の値が同じならば同じオブジェクトです。 12
>>> num_1 = 143748927394325 >>> id(num_1) 139627296785840 >>> num_2 =
143748927394325 >>> id(num_2) # numと同じ値だけれども違うオブジェクト 139627296786576 >>> num_1 += 1 # 別のオブジェクトとして値が代入される >>> id(num_1) 139627305196544 13 Pythonでは1や2などよく使われる数値は最適化のために同じ idになります。
副作用とは • 副作用とは、オブジェクトの値を変更することです。 • 副作用を伴う操作を許容するオブジェクトを「ミュータブル」なオブジェクトといいま す。 • 「イミュータブル」なオブジェクトは副作用を許容しません。 14 例:
>>> list_1 = [1, 2] >>> list_1.append(3) >>> list_1 [1, 2, 3]
ミュータブル・イミュータブルなオブジェクト • ミュータブルなオブジェクトの例 List型、Dict型、Set型… のオブジェクト • イミュータブルなオブジェクトの例 int型、str型、Tuple型… のオブジェクト 15
副作用を伴わない操作の場合① >>> name_1 = 'aaa' # str型のイミュータブルなオブジェクト >>> id(name_1) 139720897350384
>>> name_1.replace('a', 'b') # nameとは別オブジェクトを生成する、副作用 のない操作 'bbb' >>> name_1 # 上記のreplaceでname値は変更されていないのでidはそのまま 'aaa' 16
副作用を伴わない操作の場合② >>> name_1 = 'aaa' # str型のイミュータブルなオブジェクト >>> name_2 =
name_1 >>> name_1 = 'bbb' # nameは1行目とは別のオブジェクトになります。 >>> name_2 # str型はイミュータブルなのでname_2には影響はありません。 'aaa' 17
18 name name_2 オブジェク ト① name name_2 オブジェク ト① オブジェク
ト② name = 'bbb'
副作用を伴わない操作の場合③ >>> list_1 = [1, 2, 3] # List型のミュータブルなオブジェクト >>>
list_2 = list_1 + [4] # list_1の値が変わらないイミュータブルな操作 >>> list_2 [1, 2, 3, 4] >>> list_1 [1, 2, 3] 19
副作用を伴わない操作の場合④ >>> id(list_1) 140410856800704 >>> id(list_2) 140410884215232 20
副作用を伴う操作の場合① >>> list_1 = [1, 2, 3] # List型のミュータブルなオブジェクト >>>
id(list_1) 139720897421120 >>> list_1.append(4) # list_1の値を変更する副作用を伴う処理 >>> list_1 [1, 2, 3, 4] >>> id(list_1) # ミュータブルなので値が変わりオブジェクトは同じまま 139720897421120 21
副作用を伴う操作の場合② >>> list_2 = list_1 >>> list_1.append(5) >>> list_1 [1,
2, 3, 4, 5] >>> list_2 # list_1とlist_2は同じオブジェクトを指したままなのでlist_2も 変更 [1, 2, 3, 4, 5] 22
list_2の値が変わらないようにするには copy.copyを使いましょう。 23 >>> list_1 = [1, 2, 3] >>>
list_2 = copy.copy(list_1) >>> list_1.append(4) >>> list_1 [1, 2, 3, 4] >>> list_2 [1, 2, 3]
copy.copyを使うと何が起こるか 代入元の変数の値がコピーされたオブジェクトが渡されて 別のオブジェクトとなります。 24 >>> list_1 = [1, 2, 3]
>>> list_2 = copy.copy(list_1) >>> id(list_1) 140594427010048 >>> id(list_2) 140594427023056
まとめ • 副作用とは、オブジェクトの値を変更することです。 • 副作用を伴う操作を許容しないのがイミュータブルなオブジェクト。 • 副作用を伴う操作を許容するのがミュータブルなオブジェクト。 • ミュータブルな型の変数を別の変数に代入したら 変数の変更が別の変数にも反映されます。
• ミュータブルな変数を別の変数に代入したいならcopy.copyを使いましょう。 ご清聴ありがとうございました。 25
[おまけ] list_1とlist_2の値は何になるでしょうか? >>> def add_number(numbers_list: List[int], number: int) -> List[int]:
... numbers_list.append(number) ... return numbers_list >>> >>> list_1 = [1, 2, 3] >>> list_2 = add_number(l, 4) 26
list_2には値が変わってほしくなかったのに… >> # 正解は… >>> list_1 [1, 2, 3, 4]
>>> list_2 [1, 2, 3, 4] 27
copy.copyで意図しない値の変化を防ぎましょう >>> def add_number(numbers_list: List[int], number: int) -> List[int]: ...
added_list = copy.copy(numbers_list) ... added_list.append(number) ... return added_list 28