クラスによるデコレータ
次のコードを実行したときの出力として、正しいものを1つ選べ。
class C:
def __init__(self, f):
self.f = f
self.n = 0
def __call__(self, *a):
self.n += 1
return self.f(*a)
@C
def add(x, y):
return x + y
add(1, 2); add(3, 4)
print(add.n)
- A
0 - B
1 - C
2 - D
AttributeErrorが発生する。
正解と解説を見る
正解:C
__call__ を持つクラスは、関数のように呼べる。クラスのデコレータは、状態を持てるのが利点。関数のデコレータでは、クロージャを使う。
| 順 | 実行する行 | 実行後の変数 |
|---|---|---|
| 1 | `class C:` | — |
| 2 | └ `def __init__(self, f):` | — |
| 3 | └ `def __call__(self, *a):` | — |
| 4 | `@C` | — |
| 5 | `def add(x, y):` | — |
| 6 | `@C` | — |
| 7 | └ `self.f = f` | — |
| 8 | └ `self.n = 0` | — |
| 9 | `def add(x, y):` | — |
| 10 | `add(1, 2); add(3, 4)` | — |
| 11 | └ `self.n += 1` | — |
| 12 | └ `return self.f(*a)` | a = (1, 2) |
| 13 | └ `return x + y` | x = 1, y = 2 |
| 14 | └ `self.n += 1` | — |
| 15 | └ `return self.f(*a)` | a = (3, 4) |
| 16 | └ `return x + y` | x = 3, y = 4 |
| 17 | `print(add.n)` | — |
| 結果 | 実際の出力 | 2 |
- A
誤り。呼び出しのたびに増える。
- B
誤り。2 回呼んでいる。
- C
正しい。クラスをデコレータにすると、関数がそのクラスのインスタンスに置き換わり、呼び出しは
__call__に渡る。状態(呼び出し回数)を持てる。 - D
誤り。
addはCのインスタンスで、nを持つ。
このサイトの問題は、各試験の公式に示された出題範囲に沿って作ったオリジナルの模擬問題です。本試験の問題ではありません。一般社団法人Pythonエンジニア育成推進協会の公式サービスではありません。