11.. include :: include.rst
22
3- **************************************************************************
3+ ****************************************************
44Session Eight: More OO: Properties, Special methods.
5- **************************************************************************
5+ ****************************************************
66
77
88================
@@ -27,8 +27,6 @@ Lightning Talks Today:
2727
2828 Paul Briant
2929
30- Brandon Chavis
31-
3230 Jay Raina
3331
3432 Josh Hicks
@@ -48,7 +46,7 @@ The bulk of the homework for the rest of the class will be a personal project:
4846* I don't require any specific python features (i.e. classes): use
4947 what is appropriate for your project
5048
51- * Due the Friday after the last class (December 11)
49+ * Due the Sunday after the last class (December 11)
5250
5351|
5452| By next week, send me a project proposal: short and sweet.
@@ -75,10 +73,164 @@ And there is no need to check if it's empty before trying to loop through it.
7573
7674 no need for ``!= {} `` -- an empty dict is "Falsey"
7775
78- **but ** no need for that check at all. If the dict (or ist , or tuple) is
76+ **but ** no need for that check at all. If the dict (or list , or tuple) is
7977empty, then the loop is a do-nothing operation:
8078
81- * notes on Duck Typing: :ref: `exercise_html_renderer ` and code review
79+ .. code-block :: python
80+
81+ for key, value in self .attributes.items():
82+ self .atts += ' {} ="{} "' .format(key, value)
83+
84+ will not run if self.attributes is an empty dict.
85+
86+
87+ Dynamic typing and class attributes
88+ -----------------------------------
89+
90+ * what happens if we change a class attribute after creating instances??
91+
92+ - let's try ``Element.indent `` ...
93+
94+ * setting an instance attribute overwrites class attributes:
95+
96+ ``self.tag = `` overrights the class attribute (sort of!)
97+
98+ Let's experiment with that.
99+
100+
101+ dict as switch
102+ --------------
103+
104+ .. rst-class :: medium
105+
106+ What to use instead of "switch-case"?
107+
108+ A number of languages have a "switch-case" construct::
109+
110+ switch(argument) {
111+ case 0:
112+ return "zero";
113+ case 1:
114+ return "one";
115+ case 2:
116+ return "two";
117+ default:
118+ return "nothing";
119+ };
120+
121+ How do you spell this in python?
122+
123+ ``if-elif `` chains
124+ -------------------
125+
126+ The obvious way to spell it is a chain of ``elif `` statements:
127+
128+ .. code-block :: python
129+
130+ if argument == 0 :
131+ return " zero"
132+ elif argument == 1 :
133+ return " one"
134+ elif argument == 2 :
135+ return " two"
136+ else :
137+ return " nothing"
138+
139+ And there is nothing wrong with that, but....
140+
141+ .. nextslide ::
142+
143+ The ``elif `` chain is neither elegant nor efficient.
144+
145+ There are a number of ways to spell it in python -- one elegant one is to use a dict:
146+
147+ .. code-block :: python
148+
149+ arg_dict = {0 :" zero" , 1 :" one" , 2 : " two" }
150+ dict .get(argument, " nothing" )
151+
152+ Simple, elegant, and fast.
153+
154+ You can do a dispatch table by putting functions as the value.
155+
156+ Example: Chris' mailroom2 solution.
157+
158+ Polymorphism as switch:
159+ -----------------------
160+
161+ It turns out that a lot of uses of switch-case in non-OO languages is to
162+ change behaviour depending on teh type of object being worked on::
163+
164+ switch(object.tag) {
165+ case 'html':
166+ render_html_element;
167+ case 'p':
168+ render_p_element;
169+ ...
170+
171+ I saw some of this in the html renderer:
172+
173+ .. nextslide ::
174+
175+ .. code-block :: python
176+
177+ def render (out_file , ind = " " ):
178+ ... .
179+ if self .tag == ' html' :
180+ tag = " <html>"
181+ end_tag = " </html>"
182+ elif self .tag == ' p' :
183+ tag = " <p>"
184+ end_tag = " </p>"
185+
186+ This will work, of course, but:
187+
188+ * it means you need to know every tag that you might render when you write this render method.
189+
190+ * In a more complex system, you will need to go update all sorts of things all over teh place when you add a tag.
191+
192+ * It means anyone extending the system with more tags needs to edit the core base class.
193+
194+ Polymorphism
195+ ------------
196+
197+ The alternative is to use polymorphism:
198+
199+ Your ``render() `` method doesn't need to know what all the objects are
200+ that it may need to render.
201+
202+ All it needs to know is that they all will have a method
203+ that does the right thing.
204+
205+ So the above becomes, simply:
206+
207+ .. code-block :: python
208+
209+ def render (out_file , ind = " " ):
210+ ... .
211+ tag, end_tag = self .make_tags()
212+
213+ This is known as polymorphism, because many different objects are behave
214+ the same way.
215+
216+ .. nextslide ::
217+
218+ This is usally handled by subclassing, so they all get all teh same
219+ methods by default, and you only need to specialize the ones that need it.
220+
221+ But in Python -- it can be done with duck-typing instead, as the TextWrapper example.
222+
223+ Duck typing and EAFP
224+ --------------------
225+
226+ * notes on Duck Typing: :ref: `exercise_html_renderer `
227+
228+ * put the ``except `` as close as you can to where you expect an exception to be raised!
229+
230+ * Let's look at a couple ways to do that.
231+
232+ Code Review
233+ -----------
82234
83235* anyone stuck that wants to work through your code?
84236
@@ -90,10 +242,12 @@ Lightning Talks:
90242.. rst-class :: medium
91243
92244 |
93- | Paul Briant
245+ | Paul Briant
94246 |
95- | Brandon Chavis
247+ | Jay Raina
96248 |
249+ | Josh Hicks
250+
97251
98252
99253==========
@@ -261,17 +415,6 @@ For now, Let's do steps 1-4 of:
261415
262416:ref: `exercise_circle_class `
263417
264- Lightning talks:
265- -----------------
266-
267- .. rst-class :: medium
268-
269- |
270- | Jay N Raina
271- |
272- | Josh Hicks
273- |
274-
275418
276419========================
277420Static and Class Methods
@@ -289,7 +432,6 @@ Static and Class Methods
289432 And you've seen how you can call *unbound * methods on a class object so
290433 long as you pass an instance of that class as the first argument.
291434
292- |
293435
294436 .. rst-class :: centered
295437
0 commit comments