comparison doc/v2_planning/API_coding_style.txt @ 1159:531e77fb67f2

coding_style: Moved more elements to official 'API'
author Olivier Delalleau <delallea@iro>
date Fri, 17 Sep 2010 12:05:14 -0400
parents d7192e52653e
children 4f1b9e0a1377
comparison
equal deleted inserted replaced
1156:f2105a06201c 1159:531e77fb67f2
61 ~~~~~~~~ 61 ~~~~~~~~
62 62
63 We emphasize here a few important topics that are found in the official 63 We emphasize here a few important topics that are found in the official
64 guidelines: 64 guidelines:
65 65
66 * Only use ASCII characters in code files.
67
68 * Code indent must be done with four blank characters (no tabs).
69
70 * Limit lines to 79 characters.
71
72 * Naming conventions: ``ClassName``, ``TOP_LEVEL_CONSTANT``,
73 ``everything_else``.
74
75 * Comments should start with a capital letter (unless the first word is a
76 code identifier) and end with a period (short inline comments may skip
77 the period at the end).
78
79 * Imports should be listed in alphabetical order. It makes it easier to
80 verify that something is imported, and avoids duplicated imports.
81
82 * Use absolute imports only. This is compatible across a wider range of
83 Python versions, and avoids confusion about what is being
84 imported.
85
66 * Avoid using lists if all you care about is iterating on something. Using 86 * Avoid using lists if all you care about is iterating on something. Using
67 lists: 87 lists:
68 - uses more memory (and possibly more CPU if the code may break out of 88
69 the iteration), 89 - uses more memory (and possibly more CPU if the code may break out of
70 - can lead to ugly code when converted to Python 3 with 2to3, 90 the iteration),
71 - can have a different behavior if evaluating elements in the list has 91 - can lead to ugly code when converted to Python 3 with 2to3,
72 side effects (if you want these side effects, make it explicit by 92 - can have a different behavior if evaluating elements in the list has
73 assigning the list to some variable before iterating on it). 93 side effects (if you want these side effects, make it explicit by
94 assigning the list to some variable before iterating on it).
74 95
75 +------------------------+------------------------+ 96 +------------------------+------------------------+
76 | Iterative version | List version | 97 | Iterative version | List version |
77 +========================+========================+ 98 +========================+========================+
78 | .. code-block:: python | .. code-block:: python | 99 | .. code-block:: python | .. code-block:: python |
98 119
99 # Good. 120 # Good.
100 for f_x in imap(f, x): 121 for f_x in imap(f, x):
101 ... 122 ...
102 all_f_x = map(f, x) 123 all_f_x = map(f, x)
103 map(f, x) 124 map(f, x) # f has some side effect.
104 # Bad. 125 # Bad.
105 for element in map(f, x): 126 for element in map(f, x):
106 ... 127 ...
107 imap(f, x) 128 imap(f, x)
108 129
130 has_substring = substring in my_string 151 has_substring = substring in my_string
131 # Bad. 152 # Bad.
132 has_key = my_dict.has_key(key) 153 has_key = my_dict.has_key(key)
133 has_substring = my_string.find(substring) >= 0 154 has_substring = my_string.find(substring) >= 0
134 155
156 * Do not use mutable arguments as default values. Instead, use a helper
157 function (conditional expressions are forbidden at this point, see
158 below).
159
160 .. code-block:: python
161
162 # Good.
163 def f(array=None):
164 array = pylearn.if_none(array, [])
165 ...
166 # Bad.
167 def f(array=[]): # Dangerous if `array` is modified down the road.
168 ...
169
170 * Use a leading underscore '_' in names of internal attributes / methods,
171 but avoid the double underscore '__' unless you know what you are
172 doing.
173
135 174
136 Additional Recommendations 175 Additional Recommendations
137 -------------------------- 176 --------------------------
138 177
139 Things you should do even if they are not listed in official guidelines: 178 Things you should do even if they are not listed in official guidelines:
179
180 * No conditional expression (not supported in Python 2.4). These are
181 expressions of the form ``x = y if condition else z``.
182
183 * Use ``//`` for integer division and ``/ float(...)`` if you want the
184 floating point operation (for readability and compatibility across all
185 versions of Python).
186
187 .. code-block:: python
188
189 # Good.
190 n_samples_per_split = n_samples // n_splits
191 mean_x = sum(x) / float(len(x))
192 # Bad.
193 n_samples_per_split = n_samples / n_splits
194 mean_x = sum(x) / len(x)
195
196 * Always raise an exception with ``raise MyException(args)`` where ``MyException``
197 inherits from ``Exception``. This is required for compatibility across
198 all versions of Python.
199
200 .. code-block:: python
201
202 # Good.
203 raise NotImplementedError('The Pylearn team is too lazy.')
204 # Bad.
205 raise NotImplementedError, 'The Pylearn team is too lazy.'
206 raise 'The Pylearn team is too lazy to implement this.'
207
208 * Use either ``try ... except`` or ``try ... finally``, but do not mix
209 ``except`` with ``finally`` (which is not supported in Python 2.4).
210 You can however embed one into the other to mimic the ``try ... except ...
211 finally`` behavior.
212
213 .. code-block:: python
214
215 # Good.
216 try:
217 try:
218 something_that_may_fail()
219 except SomeError:
220 do_something_if_it_failed()
221 finally:
222 always_do_this_regardless_of_what_happened()
223 # Bad.
224 try:
225 something_that_may_fail()
226 except SomeError:
227 do_something_if_it_failed()
228 finally:
229 always_do_this_regardless_of_what_happened()
230
231 * Do not use the ``all`` and ``any`` builtin functions (they are not supported
232 in Python 2.4). Instead, import them from ``theano.gof.python25`` (or
233 use ``numpy.all`` / ``numpy.any`` for array data).
234
235 * Do not use the ``hashlib`` module (not supported in Python 2.4). We will
236 probably provide a wrapper around it to be compatible with all Python
237 versions.
140 238
141 * Avoid backslashes whenever possible. They make it more 239 * Avoid backslashes whenever possible. They make it more
142 difficult to edit code, and they are ugly (as well as potentially 240 difficult to edit code, and they are ugly (as well as potentially
143 dangerous if there are trailing white spaces). 241 dangerous if there are trailing white spaces).
144 242
191 my_bar, 289 my_bar,
192 my_love, 290 my_love,
193 my_everything]: 291 my_everything]:
194 ... 292 ...
195 293
294 * Use the ``key`` argument instead of ``cmp`` when sorting (for Python 3
295 compatibility).
296
297 .. code-block:: python
298
299 # Good.
300 my_list.sort(key=abs)
301 # Bad.
302 my_list.sort(cmp=lambda x, y: cmp(abs(x), abs(y)))
303
304 * Whenever you read / write binary files, specify it in the mode ('rb' for
305 reading, 'wb' for writing). This is important for cross-platform and
306 Python 3 compatibility (e.g. when pickling / unpickling objects).
307
308 .. code-block:: python
309
310 # Good.
311 cPickle.dump(obj, open('my_obj.pkl', 'wb', protocol=-1))
312 # Bad.
313 cPickle.dump(obj, open('my_obj.pkl', 'w', protocol=-1))
314
315 * Avoid tuple parameter unpacking as it can lead to very ugly code when
316 converting to Python 3.
317
318 .. code-block:: python
319
320 # Good.
321 def f(x, y_z):
322 y, z = y_z
323 ...
324 # Bad.
325 def f(x, (y, z)):
326 ...
327
328 * Only use ``cPickle``, not ``pickle`` (except for debugging purpose since
329 error messages from ``pickle`` are sometimes easier to understand).
330
331 * A script's only top-level code should be something like:
332
333 .. code-block:: python
334
335 if __name__ == '__main__':
336 sys.exit(main())
337
196 338
197 The ``logging`` Module vs. the ``warning`` Module 339 The ``logging`` Module vs. the ``warning`` Module
198 ================================================= 340 =================================================
199 341
200 The ``logging`` Module 342 The ``logging`` Module