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
厳しさとゆるさの間で迷う人に捧げる個人開発記
mizzsugar
0
14
SQLModel入門〜クエリと型〜
mizzsugar
1
650
フルリモート向いてないと思っていた私が、なんだかんだ健やかに 1年半フルリモート出来ている話
mizzsugar
0
120
Djangoでのプロジェクトだって型ヒントを運用出来る!
mizzsugar
4
8.3k
「動くものは作れる」の一歩先へ 〜「自走プログラマー」の紹介〜
mizzsugar
0
540
pytestの第一歩 〜「テスト駆動Python」の紹介〜
mizzsugar
3
320
データ分析ツール開発でpoetryを使う選択肢
mizzsugar
1
1.1k
unittest.mockを使ってテストを書こう
mizzsugar
5
6.2k
Djangoのパスワードハッシュアルゴリズムで_PyramidのWebアプリケーション作った.pdf
mizzsugar
0
860
Other Decks in Programming
See All in Programming
国漢文混用体からHolloまで
minhee
1
120
私の愛したLaravel 〜レールを超えたその先へ〜
kentaroutakeda
12
3.7k
なぜselectはselectではないのか
taiyow
2
320
複雑なフォームと複雑な状態管理にどう向き合うか / #newt_techtalk vol. 15
izumin5210
4
3.7k
ローコードサービスの進化のためのモノレポ移行
taro28
1
350
Vibe Codingをせずに Clineを使っている
watany
10
4k
AI Coding Agent Enablement - エージェントを自走させよう
yukukotani
12
3.9k
Devinのメモリ活用の学びを自社サービスにどう組み込むか?
itarutomy
0
1.9k
Return of the Full-Stack Developer
simas
PRO
1
330
コンテナでLambdaをデプロイするときに知っておきたかったこと
_takahash
0
160
Do Dumb Things
mitsuhiko
0
370
ベクトル検索システムの気持ち
monochromegane
30
9.5k
Featured
See All Featured
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
45
9.5k
Thoughts on Productivity
jonyablonski
69
4.5k
GitHub's CSS Performance
jonrohan
1030
460k
Build The Right Thing And Hit Your Dates
maggiecrowley
34
2.6k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
177
52k
Embracing the Ebb and Flow
colly
85
4.6k
Speed Design
sergeychernyshev
28
870
The Language of Interfaces
destraynor
157
24k
Visualization
eitanlees
146
16k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
Automating Front-end Workflow
addyosmani
1369
200k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
30k
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