changeset 1073:3e7978201ffc

coding_style: Some more python coding guidelines
author Olivier Delalleau <delallea@iro>
date Fri, 10 Sep 2010 11:37:36 -0400
parents 2cf3ad953bf9
children ee7f34fc98fe
files doc/v2_planning/coding_style.txt
diffstat 1 files changed, 68 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/doc/v2_planning/coding_style.txt	Fri Sep 10 10:29:15 2010 -0400
+++ b/doc/v2_planning/coding_style.txt	Fri Sep 10 11:37:36 2010 -0400
@@ -209,3 +209,71 @@
      letter (the 's'): "Return the sum of elements in x" rather than
      "Returns the sum of elements in x".
 
+    * (Point to debate) I like always doing the following when subclassing
+      a class A:
+        class B(A):
+            def __init__(self, b_arg_1, b_arg_2, **kw):
+                super(B, self).__init__(**kw)
+                ...
+      The point here is that the constructor always allow for extra keyword
+      arguments (except for the class at the very top of the hierarchy), which
+      are automatically passed to the parent class.
+      Pros:
+        - You do not need to repeat the parent class arguments whenever you
+          write a new subclass.
+        - Whenever you add an argument to the parent class, all child classes
+          can benefit from it without modifying their code.
+      Cons:
+        - One needs to look at the parent classes to see what these arguments
+          are.
+        - You cannot use a **kw argument in your constructor for your own
+          selfish purpose.
+        - I have no clue whether one could do this with multiple inheritance.
+        - More?
+      Question: Should we encourage this in Pylearn?
+
+   * Generally prefer list comprehensions to map / filter, as the former are
+     easier to read.
+    Yes:
+        non_comments = [line.strip() for line in my_file.readlines()
+                                     if not line.startswith('#')]
+    No:
+        non_comments = map(str.strip,
+                           filter(lambda line: not line.startswith('#'),
+                                  my_file.readlines()))
+    
+    * Use the `key` argument instead of `cmp` when sorting (for Python 3
+      compatibility).
+    Yes:
+        my_list.sort(key=abs)
+    No:
+        my_list.sort(cmp=lambda x, y: cmp(abs(x), abs(y)))
+
+    * Use // for integer division (for readability and Python 3 compatibility).
+    Yes:
+        n_samples_per_split = n_samples // n_splits
+    No:
+        n_samples_per_split = n_samples / n_splits
+
+    * Only use ASCII characters in code files.
+
+    * Code indent must be done with four blank characters (not with tabs).
+
+    * Whenever you read / write binary files, specify it in the mode ('rb' for
+      reading, 'wb' for writing). This is important for cross-platform and
+      Python 3 compatibility (e.g. when pickling / unpickling objects).
+
+    * Avoid tuple parameter unpacking to avoid very ugly code when converting
+      to Python 3.
+    Yes:
+        def f(x, y_z):
+            y, z = y_z
+    No:
+        def f(x, (y, z))
+
+    * Only use cPickle, not pickle.
+
+    * Always raise exception with
+        raise MyException(args)
+      where MyException inherits from Exception.
+