@@ -14,4 +14,306 @@ KN Pythona wita na kursie Pythona.
14
14
15
15
Plan:
16
16
17
- + Zarządzane atrybuty
17
+ + Zarządzane atrybuty
18
+
19
+
20
+ # Po co zarządza się atrybutami?
21
+
22
+ ``` python
23
+ person.name # pobranie wartości
24
+ person.name = wartość # przypisanie wartości
25
+ ```
26
+
27
+
28
+ # Czym jest obiekt?
29
+
30
+ ``` python
31
+ {
32
+ atrybut
33
+ metoda
34
+ {
35
+ atrybut
36
+ }
37
+ }
38
+ ```
39
+
40
+
41
+
42
+ # Zarządzanie dostępem
43
+
44
+ ``` python
45
+ class Person :
46
+ def get_name (self ):
47
+ if not valid(self .name):
48
+ raise TypeError ()
49
+ else :
50
+ return self .name.transform()
51
+ def set_name (self , value ):
52
+ if not valid(value):
53
+ raise TypeError ()
54
+ else :
55
+ self .name = transform(value)
56
+ ```
57
+
58
+
59
+
60
+ # Kod wykonywalny w miejscu dostępu
61
+
62
+ Inne podejścia:
63
+
64
+ - Metody _ getattr_ oraz _ setattr_
65
+ - Metoda _ getattribute_
66
+ - Funkcja property
67
+ - Protokół deskryptora
68
+
69
+
70
+
71
+ # Właściwości
72
+
73
+ ``` python
74
+ attribute = property (fget, fset, fdel, doc)
75
+ ```
76
+
77
+
78
+ # Właściwości
79
+
80
+ ``` python
81
+ class Person :
82
+ def __init__ (self , name ):
83
+ self ._name = name
84
+ def get_name (self ):
85
+ return self ._name
86
+ def set_name (self , value ):
87
+ self ._name = value
88
+ def del_name (self ):
89
+ del self ._name
90
+ name = property (get_name, set_name, del_name, ' name' )
91
+ ```
92
+
93
+
94
+ # Obliczanie atrybutów
95
+
96
+ ``` python
97
+ class PropSquare :
98
+ def __init__ (self , start ):
99
+ self .value = start
100
+ def get_x (self ):
101
+ return self .value ** 2
102
+ def set_x (self , value ):
103
+ self .value = value
104
+ x = property (get_x, set_x)
105
+ ```
106
+
107
+
108
+ # Właściwości jako dekoratory
109
+
110
+ ``` python
111
+ class Person :
112
+ def __init__ (self , name ):
113
+ self ._name = name
114
+ @ property
115
+ def name (self ):
116
+ " Dokumentacja name"
117
+ return self ._name
118
+ @name.setter
119
+ def name (self , value ):
120
+ self ._name = value
121
+ @name.deleter
122
+ def name (self ):
123
+ del self ._name
124
+ ```
125
+
126
+
127
+ # Deskryptory
128
+
129
+ Właściwości są uproszczonymi deskryptorami.
130
+
131
+
132
+ # Deskryptory
133
+
134
+ ``` python
135
+ class Descriptor :
136
+ ' Doc string'
137
+ def __get__ (self , instance , owner ): ...
138
+ def __set__ (self , instance , value ): ...
139
+ def __delete__ (self , instance ): ...
140
+ ```
141
+
142
+
143
+ # Deskryptory
144
+
145
+ ``` python
146
+ class Descriptor :
147
+ def __get__ (self , instance , owner ):
148
+ print (self , instance, owner)
149
+ class Subject :
150
+ attr = Descriptor()
151
+ x = Subject()
152
+ x.attr
153
+ # <..main..Descriptor <main subject <class Subject
154
+ Subject.attr
155
+ # <..main..Descriptor None <class Subject
156
+ ```
157
+
158
+
159
+ # Deskryptory
160
+
161
+ ``` python
162
+ class D :
163
+ def __get__ (* args ): print (' hop' )
164
+ class C :
165
+ a = D()
166
+ X = C()
167
+ X.a # hop
168
+ C.a # hop
169
+ X.a = 99
170
+ X.a # 99
171
+ C.a # hop
172
+ ```
173
+
174
+
175
+ # Deskryptory tylko do odczytu
176
+
177
+ ``` python
178
+ class D :
179
+ def __get__ (* args ): return 1234
180
+ def __set__ (* args ): raise AttributeError ()
181
+ class C :
182
+ a = D()
183
+ x = C()
184
+ x.a # 1234
185
+ x.a = 12 # AttributeError...
186
+ ```
187
+
188
+
189
+ # Deskrtyptory
190
+
191
+ ``` python
192
+ class Name :
193
+ def __get__ (self , instance , owner ):
194
+ return instance._name
195
+ def __set__ (self , instance , value ):
196
+ instance._name = value
197
+ def __delete__ (self , instance ):
198
+ del instance._name
199
+ class Person :
200
+ name = Name()
201
+ ```
202
+
203
+
204
+ # Deskryptory a klasy osadzone
205
+
206
+ ``` python
207
+ class A :
208
+ class B :
209
+ def __get__ (* args ): return 1234
210
+ a = B()
211
+ ```
212
+
213
+
214
+ # Informacja o stanie w deskryptorze
215
+
216
+ ``` python
217
+ class B :
218
+ def __init__ (self ):
219
+ self .cnt = 0
220
+ def __get__ (* args ):
221
+ self .cnt += 1
222
+ print (self .cnt)
223
+ return 1234
224
+ class A :
225
+ a = B()
226
+ x = A()
227
+ x.a # 1 1234
228
+ x.a # 2 1234
229
+ ```
230
+
231
+
232
+ # Metody getattr oraz getattribute
233
+
234
+ Różnica:
235
+
236
+ - metoda _ getattr_ : niezdefiniowane atrybuty
237
+ - metoda _ getattribute_ : każdy atrybut
238
+
239
+
240
+
241
+ # Zarządzanie atrybutami
242
+
243
+ ``` python
244
+ def __getattr__ (self , name ) # niezdefiniowane
245
+ def __getattribute__ (self , name ) # wszystkie
246
+ def __setattr__ (self , name , value ) # wszystkie
247
+ def __delattr__ (self , name ) # wszystkie
248
+ ```
249
+
250
+
251
+ # Zarządzane atrybuty
252
+
253
+ ``` python
254
+ class Wrapper :
255
+ def __init__ (self , object ):
256
+ self .wrapped = object
257
+ def __getattr__ (self , attrname ):
258
+ print (' Śledzenie: ' + attrname)
259
+ return getattr (self .wrapped, attrname)
260
+ ```
261
+
262
+
263
+
264
+ # Zagadka
265
+
266
+ ``` python
267
+ class A :
268
+ def __getattribute__ (self , name ):
269
+ return self .other
270
+ x = A()
271
+ print (x.abc)
272
+ ```
273
+
274
+
275
+ # Zagadka - rozwiązanie
276
+
277
+ ``` python
278
+ RecursionError !
279
+ ```
280
+
281
+
282
+
283
+ # Zagadka - kod
284
+
285
+ ``` python
286
+ class A :
287
+ def __getattribute__ (self , name ):
288
+ return object .__getattribute__ (self , ' other' )
289
+ ```
290
+
291
+
292
+
293
+ # Pętla nr 2
294
+
295
+ ``` python
296
+ class A :
297
+ def __setattr__ (self , attrname , value ):
298
+ self .other = value # pętla!
299
+ ```
300
+
301
+
302
+ # Pętla nr 2 - rozwiązanie
303
+
304
+ ``` python
305
+ class A :
306
+ def __setattr__ (self , attrname , value ):
307
+ self .__dict__ [' other' ] = value
308
+ ```
309
+
310
+
311
+ # Pętla nr 1 - CD
312
+
313
+ ``` python
314
+ class A :
315
+ def __getattribute__ (self , attrname ):
316
+ return self .__dict__ [attrname] # ?
317
+ ```
318
+
319
+
0 commit comments