More elimination of redundancy with the Google Python Style Guide.
The sections on Default Iterators And Operators, Generators, Using
apply, filter, map, reduce, Lambda Functions, and Default Argument
Values are dropped.
A section on Function Arguments is added, as it appears that
"Always pass positional arguments positionally and keyword
arguments by keyword" hasn't yet made it into the Google Python
Style Guide.
diff --git a/PythonStyleGuide.wiki b/PythonStyleGuide.wiki
index 2720891..318b583 100644
--- a/PythonStyleGuide.wiki
+++ b/PythonStyleGuide.wiki
@@ -30,11 +30,7 @@
== Python Language Rules ==
# [PythonStyleGuide#Imports Imports]: _Import only modules and only by name *(no wildcard imports)*_
- # [PythonStyleGuide#Default_Iterators_and_Operators Default Iterators and Operators]: _Yes_
- # [PythonStyleGuide#Generators Generators]: _Yes_
- # [PythonStyleGuide#Using_apply_filter_map_reduce Using apply, filter, map, reduce]: _Yes, *for one-liners*_
- # [PythonStyleGuide#Lambda_functions Lambda functions]: _Yes, *for one-liners*_
- # [PythonStyleGuide#Default_Argument_Values Default Argument Values]: _Yes_
+ # [PythonStyleGuide#Function_Arguments Function Arguments]: _Yes_
# [PythonStyleGuide#Properties Properties]: _Yes_
# [PythonStyleGuide#True_False_evaluations True/False evaluations]: _Yes_
# [PythonStyleGuide#Boolean_built_in_type Boolean built-in type]: _Yes_
@@ -105,172 +101,18 @@
without the full package name. This might cause the package to be imported
twice and have unintended side effects.
-== Default Iterators and Operators ==
+== Function Arguments ==
-*What they are:* Container types, like dictionaries and lists, define
-default iterators and membership test operators (e.g `in` and `not in`).
+*What they are:* Arguments passed to functions either by position or by name.
-*Pros:* The default iterators and operators are simple and efficient. They
-express the operation directly, without extra method calls. A function that
-uses default operators is generic. It can be used with any type that
-supports the operation.
+*Pros:* Passing arguments always by name can help code be self-documenting.
-*Cons:* You can't tell the type of objects by reading the method names
-(e.g. `has_key()` means a dictionary). This is also an advantage.
+*Cons:* Passing positional arguments by name can make a call site appear as
+though all arguments are optional. Passing keyword arguments by position can
+make a call site appear as though all arguments are required.
-*Decision:* Use default iterators and operators for types that support
-them, like lists, dictionaries, and files. The built-in types define
-iterator methods, too. Prefer these methods to methods that return
-lists, except that you should not mutate a container while iterating
-over it.
-
-*Yes:*
-
-{{{
-for key in adict: ...
-
-if key not in adict: ...
-
-if obj in alist: ...
-
-for line in afile: ...
-
-for k, v in dict.iteritems(): ...
-}}}
-
-*No:*
-
-{{{
-for key in adict.keys(): ...
-
-if not adict.has_key(key): ...
-
-for line in afile.readlines(): ...
-}}}
-
-== Generators ==
-
-*What they are:* A generator function returns an iterator that yields a
-value each time it executes a `yield` statement. After it yields a value,
-the runtime state of the generator function is suspended until the next
-value is needed.
-
-*Pros:* Simpler code, because the state of local variables and control
-flow are preserved for each call. A generator uses less memory than a
-function that creates an entire list of values at once.
-
-*Cons:* None.
-
-*Decision:* Fine. Use `"Yields:"` rather than `"Returns:"` in the
-`__doc__` string for generator functions.
-
-== Using apply filter map reduce ==
-
-*What they are*: Built-in functions useful for manipulating lists.
-Commonly used in conjunction with `lambda` functions.
-
-*Pros:* Code is compact.
-
-*Cons:* Higher-order functional programming tends to be harder to understand.
-
-*Decision:* Use list comprehensions when possible and limit use of these
-built-in functions to simple code and one-liners. In general, if such code
-gets anywhere longer than 60-80 characters or if it uses multi-level function
-calls (e.g., `map(lambda x: x[1], filter(...)))`, that's a signal that you
-are better off writing a regular loop instead. Compare:
-
-*map/filter:*
-
-{{{
-map(lambda x:x[1], filter(lambda x:x[2] == 5, my_list))
-}}}
-
-*list comprehensions:*
-
-{{{
-[x[1] for x in my_list if x[2] == 5]
-}}}
-
-== Lambda functions ==
-
-*What they are:* Lambdas define anonymous functions in an expression, as
-opposed to a statement. They are often used to define callbacks or
-operators for higher-order functions like `map()` and `filter()`.
-
-*Pros:* Convenient.
-
-*Cons:* Harder to read and debug than local functions. The lack of names
-means stack traces are more difficult to understand. Expressiveness is
-limited because the function may only contain an expression.
-
-*Decision:* OK to use them for one-liners. If the code inside the `lambda`
-function is any longer than 60-80 characters, it's probably better to define it
-as a regular (nested) function.
-
-For common operations like addition, use the functions from the operator
-module instead of `lambda` functions. For example, prefer `operator.add`
-to `lambda x, y: x + y`. (The built-in `sum()` function would be better
-than either alternative.)
-
-== Default Argument Values ==
-
-*What they are:* You can specify values for variables at the end of a
-function's parameter list, e.g., `def foo(a, b=0):`. If `foo` is called
-with only one argument, `b` is set to `0`. If it is called with two
-arguments, `b` has the value of the second argument.
-
-*Pros:* Often you have a function that uses lots of default values,
-but _rarely_ you want to override the defaults. Default argument values
-allow an easy way to do this, without having to define lots of functions
-for the rare exceptions. Also, Python does not support overloaded
-methods/functions and default arguments are an easy way of "faking"
-the overloading behavior.
-
-*Cons:* Default arguments are evaluated once at module load time. This
-may cause problems if the argument is a mutable object such as a list or
-a dictionary. If the function modifies the object (e.g., by appending an
-item to a list), the default value is modified.
-
-*Decision:* OK to use with the following caveats:
-
- * Do not use mutable objects as default values in the function or method definition.
-
-*Yes:*
-
-{{{
-def foo(a, b=None):
- if b is None:
- b = []
-}}}
-
-*No:*
-
-{{{
-def foo(a, b=[]):
- ...
-}}}
-
-Calling code must use named values for the default args. This helps
-document the code somewhat and helps prevent and detect interface
-breakage when more arguments are added.
-
-{{{
-def foo(a, b=1):
- ...
-}}}
-
-*Yes:*
-
-{{{
-foo(1)
-foo(1, b=2)
-}}}
-
-*No:*
-
-{{{
-foo(1, 2)
-}}}
+*Decision:* Always pass positional arguments positionally and keyword
+arguments by keyword.
== Properties ==
@@ -1184,4 +1026,4 @@
_Copyright 2008 Google Inc._
_This work is licensed under a_
[http://soc.googlecode.com/svn/wiki/html/licenses/cc-by-attribution-2_5.html Creative Commons Attribution 2.5 License].
-[http://creativecommons.org/licenses/by/2.5/ http://soc.googlecode.com/svn/wiki/html/licenses/cc-by-2_5-88x31.png]
\ No newline at end of file
+[http://creativecommons.org/licenses/by/2.5/ http://soc.googlecode.com/svn/wiki/html/licenses/cc-by-2_5-88x31.png]