関数に状態を持たせたい場合、一般的な方法は
のどちらかが良いと思います。どちらもほとんど同様に使えます。
クロージャの場合。
python
1def gen_f():
2 flag = True
3 def f():
4 nonlocal flag
5 if flag:
6 flag = False
7 return True
8 else:
9 return False
10 return f
11f = gen_f()
12print(f()) # => True
13print(f()) # => False
14print(f()) # => False
15
クラスの場合。
python
1class gen_f:
2 def __init__(self):
3 self.flag = True
4
5 def __call__(self):
6 if self.flag:
7 self.flag = False
8 return True
9 else:
10 return False
11
12f = gen_f()
13print(f()) # => True
14print(f()) # => False
15print(f()) # => False
他に、状態をグローバル変数に持たせる(簡単そうだけど何かとトラブルのもとにもなる)、関数オブジェクトの属性に持たせる(can110さんの方法)などがあります。
グローバル変数に持たせる場合。
python
1def f():
2 global flag
3 if flag:
4 flag = False
5 return True
6 else:
7 return False
8flag = True
9
関数オブジェクトの属性に持たせる場合(少し改良して関数のブロック内で属性を作っています。初回呼び出し時には属性が存在しないことを使います)。
python
1def f():
2 if not hasattr(f, "flag"):
3 f.flag = True
4 return True
5 return False