Mercurial > pylearn
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 |