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

回答編集履歴

4

追記

2018/09/20 17:57

投稿

umyu
umyu

スコア5846

answer CHANGED
@@ -119,4 +119,5 @@
119
119
  - [29.12. inspect — 活動中のオブジェクトの情報を取得する | docs.python.jp](https://docs.python.jp/3/library/inspect.html)
120
120
  - [Python でイベント指向のプログラミングを実現する | emptypage.jp](https://emptypage.jp/notes/pyevent.html)
121
121
  - [Does Python classes support events like other languages? | stackoverflow](https://stackoverflow.com/questions/6158602)
122
- - [Event system in Python | stackoverflow](https://stackoverflow.com/questions/1092531/event-system-in-python)
122
+ - [Event system in Python | stackoverflow](https://stackoverflow.com/questions/1092531/event-system-in-python)
123
+ - [Pythonの変数の変化を検知してEventを起こしたい | teratail](https://teratail.com/questions/124221)

3

追記

2018/09/20 17:57

投稿

umyu
umyu

スコア5846

answer CHANGED
@@ -118,4 +118,5 @@
118
118
  ■参考情報
119
119
  - [29.12. inspect — 活動中のオブジェクトの情報を取得する | docs.python.jp](https://docs.python.jp/3/library/inspect.html)
120
120
  - [Python でイベント指向のプログラミングを実現する | emptypage.jp](https://emptypage.jp/notes/pyevent.html)
121
- - [Does Python classes support events like other languages? | stackoverflow](https://stackoverflow.com/questions/6158602)
121
+ - [Does Python classes support events like other languages? | stackoverflow](https://stackoverflow.com/questions/6158602)
122
+ - [Event system in Python | stackoverflow](https://stackoverflow.com/questions/1092531/event-system-in-python)

2

追記

2018/09/20 17:48

投稿

umyu
umyu

スコア5846

answer CHANGED
@@ -116,5 +116,6 @@
116
116
  ```
117
117
 
118
118
  ■参考情報
119
- - [29.12. inspect — 活動中のオブジェクトの情報を取得する](https://docs.python.jp/3/library/inspect.html)
119
+ - [29.12. inspect — 活動中のオブジェクトの情報を取得する | docs.python.jp](https://docs.python.jp/3/library/inspect.html)
120
- - [Python でイベント指向のプログラミングを実現する](https://emptypage.jp/notes/pyevent.html)
120
+ - [Python でイベント指向のプログラミングを実現する | emptypage.jp](https://emptypage.jp/notes/pyevent.html)
121
+ - [Does Python classes support events like other languages? | stackoverflow](https://stackoverflow.com/questions/6158602)

1

追記

2018/09/20 17:34

投稿

umyu
umyu

スコア5846

answer CHANGED
@@ -1,4 +1,6 @@
1
1
  ModelからViewに通知したいという要件として認識しました。
2
+
3
+ Eventを発火させる部分はデコレータでもう少し簡単に記述できそうですが。
2
4
  こんな感じのコードでどうでしょうか。
3
5
 
4
6
  ```Python
@@ -8,15 +10,50 @@
8
10
  from pprint import pformat
9
11
 
10
12
 
13
+ class EventHandler(object):
14
+ def __init__(self):
15
+ self._observers = []
16
+
17
+ def append(self, listener):
18
+ """
19
+ Listenerの追加
20
+ :param listener:
21
+ :return:
22
+ """
23
+ assert listener is not None
24
+ if listener not in self._observers:
25
+ self._observers.append(listener)
26
+ return self
27
+
28
+ def remove(self, listener):
29
+ """
30
+ Listenerの削除
31
+ :param listener:
32
+ :return:
33
+ """
34
+ self._observers.remove(listener)
35
+ return self
36
+
37
+ def fire(self, sender: str, new_value):
38
+ for callback in self._observers:
39
+ callback(sender, new_value)
40
+
41
+ def __iadd__(self, other):
42
+ return self.append(other)
43
+
44
+ def __isub__(self, other):
45
+ return self.remove(other)
46
+
47
+
11
48
  class Model(object):
12
49
  """
13
50
  モデル
14
51
  """
15
52
  def __init__(self):
53
+ self.handler = EventHandler()
16
54
  self._TopMost = True
17
55
  self._ForeColor = "#000000"
18
56
  self._BackColor = "#000000"
19
- self._observers = []
20
57
 
21
58
  @property
22
59
  def top_most(self) -> bool:
@@ -25,7 +62,7 @@
25
62
  @top_most.setter
26
63
  def top_most(self, value: bool) -> None:
27
64
  self._TopMost = value
28
- self._fire_property_change(currentframe().f_code.co_name, value)
65
+ self.handler.fire(currentframe().f_code.co_name, value)
29
66
 
30
67
  @property
31
68
  def fore_color(self) -> str:
@@ -34,7 +71,7 @@
34
71
  @fore_color.setter
35
72
  def fore_color(self, value: str) -> None:
36
73
  self._ForeColor = value
37
- self._fire_property_change(currentframe().f_code.co_name, value)
74
+ self.handler.fire(currentframe().f_code.co_name, value)
38
75
 
39
76
  @property
40
77
  def back_color(self) -> str:
@@ -43,29 +80,8 @@
43
80
  @back_color.setter
44
81
  def back_color(self, value: str) -> None:
45
82
  self._BackColor = value
46
- self._fire_property_change(currentframe().f_code.co_name, value)
83
+ self.handler.fire(currentframe().f_code.co_name, value)
47
84
 
48
- def add_listener(self, listener):
49
- """
50
- Listenerの追加
51
- :param listener:
52
- :return:
53
- """
54
- if listener not in self._observers:
55
- self._observers.append(listener)
56
-
57
- def remove_listener(self, listener):
58
- """
59
- Listenerの削除
60
- :param listener:
61
- :return:
62
- """
63
- self._observers.remove(listener)
64
-
65
- def _fire_property_change(self, name: str, new_value):
66
- for callback in self._observers:
67
- callback(name, new_value)
68
-
69
85
  def __deepcopy__(self, memo):
70
86
  cls = self.__class__
71
87
  result = cls.__new__(cls)
@@ -78,8 +94,8 @@
78
94
  return pformat(vars(self), indent=4, width=1)
79
95
 
80
96
 
81
- def changed(aa, val):
97
+ def changed(sender, val):
82
- print(aa, val)
98
+ print(sender, val)
83
99
 
84
100
 
85
101
  def main():
@@ -87,12 +103,18 @@
87
103
  エントリーポイント
88
104
  """
89
105
  model = Model()
90
- model.add_listener(changed)
106
+ model.handler += changed
107
+ print(model)
108
+ print("#" * 60)
91
109
  model.top_most = False
92
110
  model.fore_color = "#AAAAAA"
111
+ print(model)
93
112
 
94
-
95
113
  if __name__ == '__main__':
96
114
  main()
97
115
 
98
- ```
116
+ ```
117
+
118
+ ■参考情報
119
+ - [29.12. inspect — 活動中のオブジェクトの情報を取得する](https://docs.python.jp/3/library/inspect.html)
120
+ - [Python でイベント指向のプログラミングを実現する](https://emptypage.jp/notes/pyevent.html)