回答編集履歴
1
デコレータによる実装例を追記
answer
CHANGED
@@ -32,3 +32,51 @@
|
|
32
32
|
2回目: ['test2']
|
33
33
|
3回目: list2 = ['test2'], list3 = ['test2', 'test3']
|
34
34
|
```
|
35
|
+
**追記**
|
36
|
+
|
37
|
+
デコレータ([PEP 318 – Decorators for Functions and Methods](https://peps.python.org/pep-0318/))を利用して実装してみました。
|
38
|
+
関数の属性(attribute) `__default_parameters__` にデフォルトパラメータを記録しておいて、関数が実行される度に必要に応じて関数定義時のデフォルト値に戻します。
|
39
|
+
|
40
|
+
```python
|
41
|
+
import inspect
|
42
|
+
from functools import wraps
|
43
|
+
from copy import deepcopy
|
44
|
+
|
45
|
+
def reset_default_parameter(f):
|
46
|
+
@wraps(f)
|
47
|
+
def wrapper(*args, **kwds):
|
48
|
+
if not hasattr(f, '__default_parameters__'):
|
49
|
+
# 属性 __default_parameters__ にデフォルトパラメータを記録
|
50
|
+
f.__default_parameters__ = {
|
51
|
+
k: (i, v.default) for i, (k, v) in enumerate(inspect.signature(f).parameters.items())
|
52
|
+
if v.default is not inspect.Parameter.empty
|
53
|
+
}
|
54
|
+
for k, (i, v) in f.__default_parameters__.items():
|
55
|
+
# キーワードパラメータとして指定されていない、かつ、位置パラメータでも
|
56
|
+
# 指定されていない場合に関数定義時のデフォルト値に戻す
|
57
|
+
if k not in kwds and i >= len(args):
|
58
|
+
kwds.update({k: deepcopy(v)})
|
59
|
+
return f(*args, **kwds)
|
60
|
+
return wrapper
|
61
|
+
|
62
|
+
@reset_default_parameter
|
63
|
+
def add_item(item, items=[]):
|
64
|
+
items.append(item)
|
65
|
+
return items
|
66
|
+
|
67
|
+
if __name__ == '__main__':
|
68
|
+
# 使用例
|
69
|
+
list1 = add_item("test1")
|
70
|
+
print("1回目:", list1)
|
71
|
+
|
72
|
+
list2 = add_item("test2")
|
73
|
+
print("2回目:", list2)
|
74
|
+
|
75
|
+
list3 = [1, 2, 3]
|
76
|
+
add_item('test3', list3)
|
77
|
+
print(f'{list3 = }')
|
78
|
+
|
79
|
+
# 1回目: ['test1']
|
80
|
+
# 2回目: ['test2']
|
81
|
+
# list3 = [1, 2, 3, 'test3']
|
82
|
+
```
|