teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

1

追加の質問です

2019/02/14 05:51

投稿

gunmed
gunmed

スコア55

title CHANGED
File without changes
body CHANGED
@@ -50,4 +50,94 @@
50
50
  以上のことについての回答や、自分の考えの間違いの指摘を頂けたら幸いです。
51
51
 
52
52
  mac 10.14.1
53
- visual studio code
53
+ visual studio code
54
+
55
+ ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
56
+
57
+ __defaults__と__kwdefaults__の使い方について、質問の返信スペースではわかりにくくなるため、ここに質問内容を記載します。
58
+
59
+ 以下のようなコードを作成し、使い方について自分なりに考えてみました。
60
+
61
+ ```
62
+ def func(args=[21]):
63
+ print(args)
64
+
65
+ func.__defaults__[0].append(42)
66
+ func()
67
+ #>>>[21, 42]
68
+
69
+ def kinou(args=['mail', 'address']):
70
+ print(args)
71
+
72
+ kinou.__defaults__[0].remove('mail')
73
+ kinou()
74
+ #>>>['address']
75
+
76
+ def lite(args='slim'):
77
+ print(args)
78
+ lite()
79
+ lite.__defaults__ = 'spam',
80
+ lite()
81
+
82
+ #>>>slim
83
+ # spam
84
+
85
+ ```
86
+ 関数が呼び出された際不足している実引数を補う際に利用されるとのことだったので、色々な値を動かしてみました。
87
+
88
+ LouiS0616さんが提示してくれたコードは以下でした。
89
+ ```
90
+ >>> def func(args=[]):
91
+ ... print(args)
92
+ ...
93
+ >>> func()
94
+ []
95
+ >>>
96
+ >>> func.__defaults__[0].append(42)
97
+ >>> func()
98
+ [42]
99
+ >>>
100
+ >>> func.__defaults__ = 'spam',
101
+ >>> func()
102
+ spam
103
+ ````
104
+
105
+ まず、自分が悩んだのは[0].append(42)の[0]でした。この[0]がどういった意味で置かれているのかがわからずまずは[]という空のリストにしてみるとエラーがでしまいました。
106
+ そして、たどり着いたのが自分の作ったコードのfunc関数でした。[21, 42]が結果としてでてくることから、[0]は42という実引数を入れるのに必要なもので、args=[21]を表しているのかなと思いました。しかし、[0]とするのが定義上の決まりなのかどうかがわかりませんでした。
107
+
108
+ つぎに、たどり着いたのが、kinou関数でした。appendできるならremoveもできるのかなと思い実行するとできました。やはり、[0]はargsのリストを表しているということが確信できました。
109
+
110
+ そして、func.__defaults__ = 'spam',について考えました。おそらくargs=[]の=以降を変更するのではと考え、args='slim'として行ったところ、spamに変更されていたので、=とするとデフォルト値を変更できるのではという結論に自分の中で至りました。
111
+ また、'spam',の,が気になったので、'spam'と変更してみると、
112
+
113
+ TypeError: __defaults__ must be set to a tuple object
114
+
115
+ と表示されました。一応公式では__defaults__は『デフォルト値を持つ引数に対するデフォルト値が収められたタプル』となっていたので、タプルでは('aaa',)というように,が必要だったのを思い出すと=でデフォルト値を変更する時はタプルとしての操作をする(先例のリストの追加をするときの[0]とは別)のかなと納得しましたが、そういう理解でいいのか確証はありません。
116
+
117
+ また、__kwdefaults__は公式によると、キーワード専用パラメータのデフォルト値を含む辞書となっていたので、以下のようなコードを書いて実験してみました。
118
+
119
+ ```
120
+ def moji(a, *, b='ow'):
121
+ print(a,b,sep='')
122
+
123
+ moji('r')
124
+ #>>>row
125
+
126
+ moji.__kwdefaults__ ='ing'
127
+
128
+ moji('r')
129
+ #>>>TypeError: __kwdefaults__ must be set to a dict object
130
+
131
+ ```
132
+ となってしまいました。やはり、__kwdefaults__辞書のようです。キーワード専用パラメータのデフォルト値は結果として変更できませんでした。
133
+ また、辞書のような形式で変更してみたらどうだろうと思い、先ほどのリストのように以下のようにコードを作りました。
134
+ ```
135
+ moji.__kwdefaults__ {0}['b']='ing'
136
+
137
+ moji('r')
138
+ #>>>moji.__kwdefaults__ {None:None}['b']='ing'
139
+ # ^
140
+ ```
141
+ func.__defaults__[0].append(42)のような形式で、辞書を値のない辞書として、0のかわりにNoneを使用してみましたが、エラーでした。
142
+
143
+ ネットや本を調べても詳細が見つからないので、上記の[0]の意味について、=での変更のについて、__kwdefaults__の使い方についての主に3つについて教えていただけたら幸いです。よろしくお願いします。