回答編集履歴

3

追記

2019/02/14 06:34

投稿

LouiS0616
LouiS0616

スコア35660

test CHANGED
@@ -63,3 +63,119 @@
63
63
  spam
64
64
 
65
65
  ```
66
+
67
+
68
+
69
+ 質問追記を受けて
70
+
71
+ ---
72
+
73
+ 関数オブジェクトは呼び出された際、不足する引数にデフォルト値が定められていないか調査します。
74
+
75
+ そのときにチェックされる帳簿が`__defaults__`及び`__kwdefaults__`です。
76
+
77
+
78
+
79
+ > 自分が悩んだのは[0].append(42)の[0]でした。
80
+
81
+
82
+
83
+ `__defaults__`がデフォルト値のタプルだからです。
84
+
85
+ ```Python
86
+
87
+ >>> def func(arg1=[], arg2=[]):
88
+
89
+ ... print(arg1, arg2)
90
+
91
+ ...
92
+
93
+ >>> func.__defaults__
94
+
95
+ ([], [])
96
+
97
+ >>> type(func.__defaults__)
98
+
99
+ <class 'tuple'>
100
+
101
+ >>>
102
+
103
+ >>> func.__defaults__[0]
104
+
105
+ []
106
+
107
+ >>> type(func.__defaults__[0])
108
+
109
+ <class 'list'>
110
+
111
+ >>>
112
+
113
+ >>> func.__defaults__[0].append(42)
114
+
115
+ >>> func()
116
+
117
+ [42] []
118
+
119
+ >>>
120
+
121
+ >>> func.__defaults__[1].append(6)
122
+
123
+ >>> func()
124
+
125
+ [42] [6]
126
+
127
+ ```
128
+
129
+
130
+
131
+ > func.defaults = 'spam',について考えました。おそらくargs=[]の=以降を変更するのではと考え、args='slim'として行ったところ、spamに変更されていたので、=とするとデフォルト値を変更できるのではという結論に自分の中で至りました。
132
+
133
+
134
+
135
+ その考えで問題無いように思います。
136
+
137
+ ただし関数オブジェクトの属性を書き換えているだけなので、決して特殊な文法ではありませんが。
138
+
139
+
140
+
141
+ > タプルでは('aaa',)というように,が必要だったのを思い出すと=でデフォルト値を変更する時はタプルとしての操作をする(先例のリストの追加をするときの[0]とは別)のかな
142
+
143
+
144
+
145
+ 単一要素のタプルのリテラルを記述するときは、
146
+
147
+ 文法の都合上最後にカンマ(俗称ケツカンマ)を付けなければなりません。
148
+
149
+
150
+
151
+ カンマを付けないと、計算の順序を操作する括弧と見分けが付かないからです。
152
+
153
+
154
+
155
+ > func.defaults[0].append(42)のような形式で、辞書を値のない辞書として、0のかわりにNoneを使用してみましたが、エラーでした。
156
+
157
+
158
+
159
+ やるならこんな感じでしょうか。
160
+
161
+ ```Python
162
+
163
+ >>> def moji(a, *, b='ow'):
164
+
165
+ ... print(a, b, sep='')
166
+
167
+ ...
168
+
169
+ >>> moji.__kwdefaults__
170
+
171
+ {'b': 'ow'}
172
+
173
+ >>> moji.__kwdefaults__['b'] = 'ing'
174
+
175
+ >>>
176
+
177
+ >>> moji('r')
178
+
179
+ ring
180
+
181
+ ```

2

追記

2019/02/14 06:34

投稿

LouiS0616
LouiS0616

スコア35660

test CHANGED
@@ -12,7 +12,7 @@
12
12
 
13
13
  ```Python
14
14
 
15
- >>> def func(arg=[]):
15
+ >>> def func(arg='spam', *, kwarg='ham'):
16
16
 
17
17
  ... pass
18
18
 
@@ -20,7 +20,11 @@
20
20
 
21
21
  >>> func.__defaults__
22
22
 
23
- ([],)
23
+ ('spam',)
24
+
25
+ >>> func.__kwdefaults__
26
+
27
+ {'kwarg': 'ham'}
24
28
 
25
29
  ```
26
30
 

1

追記

2019/02/13 05:14

投稿

LouiS0616
LouiS0616

スコア35660

test CHANGED
@@ -3,3 +3,59 @@
3
3
 
4
4
 
5
5
  引用元: [Python よくある質問 » なぜオブジェクト間でデフォルト値が共有されるのですか?](https://docs.python.jp/3/faq/programming.html#why-are-default-values-shared-between-objects)
6
+
7
+
8
+
9
+ ---
10
+
11
+ なお、デフォルト値は次のように確認できます。
12
+
13
+ ```Python
14
+
15
+ >>> def func(arg=[]):
16
+
17
+ ... pass
18
+
19
+ ...
20
+
21
+ >>> func.__defaults__
22
+
23
+ ([],)
24
+
25
+ ```
26
+
27
+
28
+
29
+ このことからも、**デフォルト値が関数オブジェクトに所有されている**ことが分かります。
30
+
31
+ なお、次のような不可解な操作も可能です。
32
+
33
+ ```Python
34
+
35
+ >>> def func(args=[]):
36
+
37
+ ... print(args)
38
+
39
+ ...
40
+
41
+ >>> func()
42
+
43
+ []
44
+
45
+ >>>
46
+
47
+ >>> func.__defaults__[0].append(42)
48
+
49
+ >>> func()
50
+
51
+ [42]
52
+
53
+ >>>
54
+
55
+ >>> func.__defaults__ = 'spam',
56
+
57
+ >>> func()
58
+
59
+ spam
60
+
61
+ ```