Updating python style guide

This commit is contained in:
apicard@google.com 2012-09-18 23:16:02 +00:00
parent 864b0dc238
commit 424ad34281

View File

@ -136,7 +136,7 @@
<H1>Google Python Style Guide</H1> <H1>Google Python Style Guide</H1>
<p align="right"> <p align="right">
Revision 2.29 Revision 2.39
</p> </p>
<address> <address>
@ -165,12 +165,12 @@
<TR valign="top" class=""> <TR valign="top" class="">
<TD><DIV class="toc_category"><A href="#Python_Language_Rules">Python Language Rules</A></DIV></TD> <TD><DIV class="toc_category"><A href="#Python_Language_Rules">Python Language Rules</A></DIV></TD>
<TD><DIV class="toc_stylepoint"> <TD><DIV class="toc_stylepoint">
<SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#pychecker">pychecker</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Imports">Imports</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Packages">Packages</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Exceptions">Exceptions</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Global_variables">Global variables</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Nested/Local/Inner_Classes_and_Functions">Nested/Local/Inner Classes and Functions</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#List_Comprehensions">List Comprehensions</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Default_Iterators_and_Operators">Default Iterators and Operators</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Generators">Generators</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Lambda_Functions">Lambda Functions</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Default_Argument_Values">Default Argument Values</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Properties">Properties</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#True/False_evaluations">True/False evaluations</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Deprecated_Language_Features">Deprecated Language Features</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Lexical_Scoping">Lexical Scoping</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Function_and_Method_Decorators">Function and Method Decorators</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Threading">Threading</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Power_Features">Power Features</A></SPAN> </DIV></TD> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#pychecker">pychecker</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Imports">Imports</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Packages">Packages</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Exceptions">Exceptions</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Global_variables">Global variables</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Nested/Local/Inner_Classes_and_Functions">Nested/Local/Inner Classes and Functions</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#List_Comprehensions">List Comprehensions</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Default_Iterators_and_Operators">Default Iterators and Operators</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Generators">Generators</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Lambda_Functions">Lambda Functions</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Conditional_Expressions">Conditional Expressions</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Default_Argument_Values">Default Argument Values</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Properties">Properties</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#True/False_evaluations">True/False evaluations</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Deprecated_Language_Features">Deprecated Language Features</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Lexical_Scoping">Lexical Scoping</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Function_and_Method_Decorators">Function and Method Decorators</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Threading">Threading</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Power_Features">Power Features</A></SPAN> </DIV></TD>
</TR> </TR>
<TR valign="top" class=""> <TR valign="top" class="">
<TD><DIV class="toc_category"><A href="#Python_Style_Rules">Python Style Rules</A></DIV></TD> <TD><DIV class="toc_category"><A href="#Python_Style_Rules">Python Style Rules</A></DIV></TD>
<TD><DIV class="toc_stylepoint"> <TD><DIV class="toc_stylepoint">
<SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Semicolons">Semicolons</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Line_length">Line length</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Parentheses">Parentheses</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Indentation">Indentation</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Blank_Lines">Blank Lines</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Whitespace">Whitespace</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Shebang_Line">Shebang Line</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Comments">Comments</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Classes">Classes</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Strings">Strings</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#TODO_Comments">TODO Comments</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Imports_formatting">Imports formatting</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Statements">Statements</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Access_Control">Access Control</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Naming">Naming</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Main">Main</A></SPAN> </DIV></TD> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Semicolons">Semicolons</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Line_length">Line length</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Parentheses">Parentheses</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Indentation">Indentation</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Blank_Lines">Blank Lines</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Whitespace">Whitespace</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Shebang_Line">Shebang Line</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Comments">Comments</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Classes">Classes</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Strings">Strings</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Files_and_Sockets">Files and Sockets</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#TODO_Comments">TODO Comments</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Imports_formatting">Imports formatting</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Statements">Statements</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Access_Control">Access Control</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Naming">Naming</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Main">Main</A></SPAN> </DIV></TD>
</TR> </TR>
</TABLE> </TABLE>
</DIV> </DIV>
@ -223,7 +223,7 @@
<DIV style="display:inline;" class=""> <DIV style="display:inline;" class="">
Run <code>pychecker</code> over your code. Run <code>pychecker</code> over your code.
</DIV> </DIV>
<DIV class=""><DIV class="stylepoint_body" name="pychecker__body" id="pychecker__body" style="display: none"> <DIV class=""><DIV class="stylepoint_body" name="pychecker__body" id="pychecker__body" style="display: none">
<P class=""> <P class="">
<SPAN class="stylepoint_section">Definition: </SPAN> <SPAN class="stylepoint_section">Definition: </SPAN>
PyChecker is a tool for finding bugs in Python source code. It finds PyChecker is a tool for finding bugs in Python source code. It finds
@ -243,7 +243,7 @@
Suppress its warnings c) Improve it or d) Ignore it. Suppress its warnings c) Improve it or d) Ignore it.
</P> </P>
<P class=""> <P class="">
<SPAN class="stylepoint_section">Decision: </SPAN> <SPAN class="stylepoint_section">Decision: </SPAN>
Make sure you run <code>pychecker</code> on your code. Make sure you run <code>pychecker</code> on your code.
</P> </P>
@ -254,7 +254,7 @@
</p> </p>
<p> <p>
To suppress warnings, you can set a module-level variable named To suppress warnings, you can set a module-level variable named
<code>__pychecker__</code> to suppress appropriate warnings. <code>__pychecker__</code> to suppress appropriate warnings.
For example: For example:
</p> </p>
<DIV class=""><PRE> <DIV class=""><PRE>
@ -264,7 +264,7 @@
for suppressions and revisit them. for suppressions and revisit them.
</p> </p>
<p> <p>
You can get a list of pychecker warnings by doing You can get a list of pychecker warnings by doing
<code>pychecker --help</code>. <code>pychecker --help</code>.
</p> </p>
<p> <p>
@ -276,7 +276,7 @@
</p> </p>
<DIV class=""><PRE> <DIV class=""><PRE>
<span class="external"></span>def foo(a, unused_b, unused_c, d=None, e=None): <span class="external"></span>def foo(a, unused_b, unused_c, d=None, e=None):
<span class="external"> </span>(d, e) = (d, e) # Silence pychecker <span class="external"> </span>_ = d, e
<span class="external"> </span>return a <span class="external"> </span>return a
<span class="external"></span> <span class="external"></span>
</PRE></DIV> </PRE></DIV>
@ -406,11 +406,11 @@ from sound.effects import echo
Exceptions must follow certain conditions: Exceptions must follow certain conditions:
<ul> <ul>
<li>Raise exceptions like this: <code>raise MyException("Error <li>Raise exceptions like this: <code>raise MyException('Error
message")</code> or <code>raise MyException</code>. Do not message')</code> or <code>raise MyException</code>. Do not
use the two-argument form (<code>raise MyException, "Error use the two-argument form (<code>raise MyException, 'Error
message"</code>) or deprecated string-based exceptions message'</code>) or deprecated string-based exceptions
(<code>raise "Error message"</code>).</li> (<code>raise 'Error message'</code>).</li>
<li>Modules or packages should define their own domain-specific <li>Modules or packages should define their own domain-specific
base exception class, which should inherit from the built-in base exception class, which should inherit from the built-in
Exception class. The base exception for a module should be called Exception class. The base exception for a module should be called
@ -436,6 +436,14 @@ from sound.effects import echo
<li>Use the <code>finally</code> clause to execute code whether <li>Use the <code>finally</code> clause to execute code whether
or not an exception is raised in the <code>try</code> block. or not an exception is raised in the <code>try</code> block.
This is often useful for cleanup, i.e., closing a file.</li> This is often useful for cleanup, i.e., closing a file.</li>
<li>When capturing an exception, use <code>as</code> rather than
a comma. For example:
<DIV class=""><PRE>
<span class="external"></span>try:
<span class="external"> </span>raise Error
<span class="external"></span>except Error as error:
<span class="external"> </span>pass</PRE></DIV>
</li>
</ul> </ul>
</P> </P>
</DIV></DIV> </DIV></DIV>
@ -547,15 +555,6 @@ from sound.effects import echo
permitted. Use loops instead when things get more complicated. permitted. Use loops instead when things get more complicated.
</P> </P>
<DIV class=""><PRE class="badcode">No<span class="external"></span>:
<span class="external"></span>result = [(x, y) for x in range(10) for y in range(5) if x * y &gt; 10]
<span class="external"></span>return ((x, y, z)
<span class="external"></span> for x in xrange(5)
<span class="external"></span> for y in xrange(5)
<span class="external"></span> if x != y
<span class="external"></span> for z in xrange(5)
<span class="external"></span> if y != z)</PRE></DIV>
<DIV class=""><PRE>Ye<span class="external"></span>s: <DIV class=""><PRE>Ye<span class="external"></span>s:
<span class="external"></span>result = [] <span class="external"></span>result = []
<span class="external"></span>for x in range(10): <span class="external"></span>for x in range(10):
@ -578,6 +577,15 @@ from sound.effects import echo
<span class="external"></span>eat(jelly_bean for jelly_bean in jelly_beans <span class="external"></span>eat(jelly_bean for jelly_bean in jelly_beans
<span class="external"></span> if jelly_bean.color == 'black')</PRE></DIV> <span class="external"></span> if jelly_bean.color == 'black')</PRE></DIV>
<DIV class=""><PRE class="badcode">No<span class="external"></span>:
<span class="external"></span>result = [(x, y) for x in range(10) for y in range(5) if x * y &gt; 10]
<span class="external"></span>return ((x, y, z)
<span class="external"></span> for x in xrange(5)
<span class="external"></span> for y in xrange(5)
<span class="external"></span> if x != y
<span class="external"></span> for z in xrange(5)
<span class="external"></span> if y != z)</PRE></DIV>
</DIV></DIV> </DIV></DIV>
</DIV> </DIV>
<DIV class=""> <DIV class="">
@ -586,7 +594,7 @@ from sound.effects import echo
link link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Default_Iterators_and_Operators')" name="Default_Iterators_and_Operators__button" id="Default_Iterators_and_Operators__button"></SPAN> </A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Default_Iterators_and_Operators')" name="Default_Iterators_and_Operators__button" id="Default_Iterators_and_Operators__button"></SPAN>
<DIV style="display:inline;" class=""> <DIV style="display:inline;" class="">
Use default iterators and operators for types that support them, Use default iterators and operators for types that support them,
like lists, dictionaries, and files. like lists, dictionaries, and files.
</DIV> </DIV>
<DIV class=""><DIV class="stylepoint_body" name="Default_Iterators_and_Operators__body" id="Default_Iterators_and_Operators__body" style="display: none"> <DIV class=""><DIV class="stylepoint_body" name="Default_Iterators_and_Operators__body" id="Default_Iterators_and_Operators__body" style="display: none">
@ -648,7 +656,7 @@ from sound.effects import echo
function that creates an entire list of values at once. function that creates an entire list of values at once.
</P> </P>
<P class=""> <P class="">
<SPAN class="stylepoint_section">Cons: </SPAN> <SPAN class="stylepoint_section">Cons: </SPAN>
None. None.
</P> </P>
<P class=""> <P class="">
@ -699,6 +707,37 @@ from sound.effects import echo
</DIV></DIV> </DIV></DIV>
</DIV> </DIV>
<DIV class=""> <DIV class="">
<H3><A name="Conditional_Expressions" id="Conditional_Expressions">Conditional Expressions</A></H3>
<SPAN class="link_button" id="link-Conditional_Expressions__button" name="link-Conditional_Expressions__button"><A href="?showone=Conditional_Expressions#Conditional_Expressions">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Conditional_Expressions')" name="Conditional_Expressions__button" id="Conditional_Expressions__button"></SPAN>
<DIV style="display:inline;" class="">
Okay for one-liners.
</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Conditional_Expressions__body" id="Conditional_Expressions__body" style="display: none">
<P class="">
<SPAN class="stylepoint_section">Definition: </SPAN>
Conditional expressions are mechanisms that provide a shorter syntax
for if statements. For example:
<code>x = 1 if cond else 2</code>.
</P>
<P class="">
<SPAN class="stylepoint_section">Pros: </SPAN>
Shorter and more convenient than an if statement.
</P>
<P class="">
<SPAN class="stylepoint_section">Cons: </SPAN>
May be harder to read than an if statement. The condition may be difficult
to locate if the expression is long.
</P>
<P class="">
<SPAN class="stylepoint_section">Decision: </SPAN>
Okay to use for one-liners. In other cases prefer to use a complete if
statement.
</P>
</DIV></DIV>
</DIV>
<DIV class="">
<H3><A name="Default_Argument_Values" id="Default_Argument_Values">Default Argument Values</A></H3> <H3><A name="Default_Argument_Values" id="Default_Argument_Values">Default Argument Values</A></H3>
<SPAN class="link_button" id="link-Default_Argument_Values__button" name="link-Default_Argument_Values__button"><A href="?showone=Default_Argument_Values#Default_Argument_Values"> <SPAN class="link_button" id="link-Default_Argument_Values__button" name="link-Default_Argument_Values__button"><A href="?showone=Default_Argument_Values#Default_Argument_Values">
link link
@ -726,7 +765,7 @@ from sound.effects import echo
"faking" the overloading behavior. "faking" the overloading behavior.
</P> </P>
<P class=""> <P class="">
<SPAN class="stylepoint_section">Cons: </SPAN> <SPAN class="stylepoint_section">Cons: </SPAN>
Default arguments are evaluated once at module load Default arguments are evaluated once at module load
time. This may cause problems if the argument is a mutable time. This may cause problems if the argument is a mutable
object such as a list or a dictionary. If the function modifies object such as a list or a dictionary. If the function modifies
@ -765,8 +804,8 @@ from sound.effects import echo
link link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Properties')" name="Properties__button" id="Properties__button"></SPAN> </A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Properties')" name="Properties__button" id="Properties__button"></SPAN>
<DIV style="display:inline;" class=""> <DIV style="display:inline;" class="">
Use properties for accessing or setting data where you would Use properties for accessing or setting data where you would
normally have used simple, lightweight accessor or setter methods. normally have used simple, lightweight accessor or setter methods.
</DIV> </DIV>
<DIV class=""><DIV class="stylepoint_body" name="Properties__body" id="Properties__body" style="display: none"> <DIV class=""><DIV class="stylepoint_body" name="Properties__body" id="Properties__body" style="display: none">
<P class=""> <P class="">
@ -797,7 +836,7 @@ from sound.effects import echo
<SPAN class="stylepoint_section">Decision: </SPAN> Use properties in new code to access or <SPAN class="stylepoint_section">Decision: </SPAN> Use properties in new code to access or
set data where you would normally have used simple, lightweight set data where you would normally have used simple, lightweight
accessor or setter methods. Read-only properties should be created accessor or setter methods. Read-only properties should be created
with the <code>@property</code> with the <code>@property</code>
<a HREF="#Function_and_Method_Decorators">decorator</a>. <a HREF="#Function_and_Method_Decorators">decorator</a>.
<p><a id="properties-template-dp"> <p><a id="properties-template-dp">
@ -868,7 +907,7 @@ from sound.effects import echo
<SPAN class="stylepoint_section">Definition: </SPAN> Python evaluates certain values as <code>false</code> <SPAN class="stylepoint_section">Definition: </SPAN> Python evaluates certain values as <code>false</code>
when in a boolean context. A quick "rule of thumb" is that all when in a boolean context. A quick "rule of thumb" is that all
"empty" values are considered <code>false</code> so <code>0, None, [], {}, "empty" values are considered <code>false</code> so <code>0, None, [], {},
""</code> all evaluate as <code>false</code> in a boolean context. ''</code> all evaluate as <code>false</code> in a boolean context.
</P> </P>
<P class=""> <P class="">
<SPAN class="stylepoint_section">Pros: </SPAN> Conditions using Python booleans are easier to read <SPAN class="stylepoint_section">Pros: </SPAN> Conditions using Python booleans are easier to read
@ -963,16 +1002,16 @@ from sound.effects import echo
We do not use any Python version which does not support We do not use any Python version which does not support
these features, so there is no reason not to use the new these features, so there is no reason not to use the new
styles. styles.
<DIV class=""><PRE class="badcode">No: <span class="external"></span>words = string.split(foo, ':')
<span class="external"></span>map(lambda x: x[1], filter(lambda x: x[2] == 5, my_list))
<span class="external"></span>apply(fn, args, kwargs)</PRE></DIV>
<DIV class=""><PRE>Yes: <span class="external"></span>words = foo.split(':') <DIV class=""><PRE>Yes: <span class="external"></span>words = foo.split(':')
<span class="external"></span>[x[1] for x in my_list if x[2] == 5] <span class="external"></span>[x[1] for x in my_list if x[2] == 5]
<span class="external"></span>fn(*args, **kwargs)</PRE></DIV> <span class="external"></span>fn(*args, **kwargs)</PRE></DIV>
<DIV class=""><PRE class="badcode">No: <span class="external"></span>words = string.split(foo, ':')
<span class="external"></span>map(lambda x: x[1], filter(lambda x: x[2] == 5, my_list))
<span class="external"></span>apply(fn, args, kwargs)</PRE></DIV>
</P> </P>
</DIV></DIV> </DIV></DIV>
</DIV> </DIV>
@ -995,7 +1034,7 @@ from sound.effects import echo
local variable, even if the use precedes the assignment. If a local variable, even if the use precedes the assignment. If a
global declaration occurs, the name is treated as a global global declaration occurs, the name is treated as a global
variable. variable.
<p> <p>
An example of the use of this feature is: An example of the use of this feature is:
</p> </p>
@ -1018,7 +1057,7 @@ from sound.effects import echo
</P> </P>
<P class=""> <P class="">
<SPAN class="stylepoint_section">Cons: </SPAN> <SPAN class="stylepoint_section">Cons: </SPAN>
Can lead to confusing bugs. Such as this example based on Can lead to confusing bugs. Such as this example based on
<a HREF="http://www.python.org/dev/peps/pep-0227/">PEP-0227</a>: <a HREF="http://www.python.org/dev/peps/pep-0227/">PEP-0227</a>:
<DIV class=""><PRE class="badcode"> <DIV class=""><PRE class="badcode">
<span class="external"></span>i = 4 <span class="external"></span>i = 4
@ -1034,7 +1073,7 @@ from sound.effects import echo
<p> <p>
So <code>foo([1, 2, 3])</code> will print <code>1 2 3 3</code>, not So <code>foo([1, 2, 3])</code> will print <code>1 2 3 3</code>, not
<code>1 2 3 4</code>. <code>1 2 3 4</code>.
</p> </p>
</P> </P>
<P class=""> <P class="">
<SPAN class="stylepoint_section">Decision: </SPAN> <SPAN class="stylepoint_section">Decision: </SPAN>
@ -1132,7 +1171,7 @@ from sound.effects import echo
</p> </p>
<p> <p>
Use the Queue module's <code>Queue</code> data type as the preferred Use the Queue module's <code>Queue</code> data type as the preferred
way to way to
communicate data between threads. Otherwise, use the threading communicate data between threads. Otherwise, use the threading
module and its locking primitives. Learn about the proper use module and its locking primitives. Learn about the proper use
@ -1171,7 +1210,7 @@ from sound.effects import echo
difficult than code that is longer but is straightforward. difficult than code that is longer but is straightforward.
</P> </P>
<P class=""> <P class="">
<SPAN class="stylepoint_section">Decision: </SPAN> <SPAN class="stylepoint_section">Decision: </SPAN>
Avoid these features in Avoid these features in
your code. your code.
</P> </P>
@ -1202,8 +1241,8 @@ from sound.effects import echo
</DIV> </DIV>
<DIV class=""><DIV class="stylepoint_body" name="Line_length__body" id="Line_length__body" style="display: none"> <DIV class=""><DIV class="stylepoint_body" name="Line_length__body" id="Line_length__body" style="display: none">
<p> <p>
Exception: lines importing modules may end up longer than 80 Exception: lines importing modules may end up longer than 80
characters only if using Python 2.4 or characters only if using Python 2.4 or
earlier. earlier.
</p> </p>
@ -1239,7 +1278,7 @@ from sound.effects import echo
<p> <p>
Make note of the indentation of the elements in the line Make note of the indentation of the elements in the line
continuation examples above; see the continuation examples above; see the
<a HREF="#indentation">indentation</a> <a HREF="#indentation">indentation</a>
section for explanation. section for explanation.
</p> </p>
@ -1255,8 +1294,8 @@ from sound.effects import echo
</DIV> </DIV>
<DIV class=""><DIV class="stylepoint_body" name="Parentheses__body" id="Parentheses__body" style="display: none"> <DIV class=""><DIV class="stylepoint_body" name="Parentheses__body" id="Parentheses__body" style="display: none">
<p> <p>
Do not use them in return statements or conditional statements unless Do not use them in return statements or conditional statements unless
using parentheses for implied line continuation. (See above.) using parentheses for implied line continuation. (See above.)
It is however fine to use parentheses around tuples. It is however fine to use parentheses around tuples.
</p> </p>
@ -1320,7 +1359,7 @@ from sound.effects import echo
link link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Blank_Lines')" name="Blank_Lines__button" id="Blank_Lines__button"></SPAN> </A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Blank_Lines')" name="Blank_Lines__button" id="Blank_Lines__button"></SPAN>
<DIV style="display:inline;" class=""> <DIV style="display:inline;" class="">
Two blank lines between top-level definitions, one blank line Two blank lines between top-level definitions, one blank line
between method definitions. between method definitions.
</DIV> </DIV>
<DIV class=""><DIV class="stylepoint_body" name="Blank_Lines__body" id="Blank_Lines__body" style="display: none"> <DIV class=""><DIV class="stylepoint_body" name="Blank_Lines__body" id="Blank_Lines__body" style="display: none">
@ -1339,7 +1378,7 @@ from sound.effects import echo
link link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Whitespace')" name="Whitespace__button" id="Whitespace__button"></SPAN> </A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Whitespace')" name="Whitespace__button" id="Whitespace__button"></SPAN>
<DIV style="display:inline;" class=""> <DIV style="display:inline;" class="">
Follow standard typographic rules for the use of spaces around Follow standard typographic rules for the use of spaces around
punctuation. punctuation.
</DIV> </DIV>
<DIV class=""><DIV class="stylepoint_body" name="Whitespace__body" id="Whitespace__body" style="display: none"> <DIV class=""><DIV class="stylepoint_body" name="Whitespace__body" id="Whitespace__body" style="display: none">
@ -1395,16 +1434,16 @@ from sound.effects import echo
long_name = 2 # comment that should not be aligned long_name = 2 # comment that should not be aligned
dictionary = { dictionary = {
"foo": 1, 'foo': 1,
"long_name": 2, 'long_name': 2,
}</PRE></DIV> }</PRE></DIV>
<DIV class=""><PRE class="badcode">No: <DIV class=""><PRE class="badcode">No:
foo = 1000 # comment foo = 1000 # comment
long_name = 2 # comment that should not be aligned long_name = 2 # comment that should not be aligned
dictionary = { dictionary = {
"foo" : 1, 'foo' : 1,
"long_name": 2, 'long_name': 2,
}</PRE></DIV> }</PRE></DIV>
@ -1469,15 +1508,9 @@ from sound.effects import echo
<p> <p>
Every file should contain the following items, in order: Every file should contain license boilerplate.
<ul> Choose the appropriate boilerplate for the license used by the project
<li>a copyright statement (for example, (for example, Apache 2.0, BSD, LGPL, GPL)
<code>Copyright 2008 Google Inc.</code>)</li>
<li>a license boilerplate. Choose the appropriate boilerplate
for the license used by the project (for example, Apache 2.0, BSD,
LGPL, GPL)</li>
<li>an author line to identify the original author of the file</li>
</ul>
</p> </p>
</P> </P>
<P class=""> <P class="">
@ -1616,9 +1649,9 @@ from sound.effects import echo
<p> <p>
The final place to have comments is in tricky parts of the The final place to have comments is in tricky parts of the
code. If you're going to have to explain it at the next code. If you're going to have to explain it at the next
<a HREF="http://en.wikipedia.org/wiki/Code_review">code review</a>, <a HREF="http://en.wikipedia.org/wiki/Code_review">code review</a>,
you should comment it now. Complicated operations get a few lines of you should comment it now. Complicated operations get a few lines of
comments before the operations comments before the operations
commence. Non-obvious ones get comments at the end of the line. commence. Non-obvious ones get comments at the end of the line.
</p> </p>
@ -1663,17 +1696,6 @@ from sound.effects import echo
from <code>object</code>. This also applies to nested classes. from <code>object</code>. This also applies to nested classes.
</DIV> </DIV>
<DIV class=""><DIV class="stylepoint_body" name="Classes__body" id="Classes__body" style="display: none"> <DIV class=""><DIV class="stylepoint_body" name="Classes__body" id="Classes__body" style="display: none">
<DIV class=""><PRE class="badcode">No: <span class="external"></span>class SampleClass:
<span class="external"> </span>pass
<span class="external"></span>class OuterClass:
<span class="external"> </span>class InnerClass:
<span class="external"> </span>pass
<span class="external"></span>
</PRE></DIV>
<DIV class=""><PRE>Yes: <span class="external"></span>class SampleClass(object): <DIV class=""><PRE>Yes: <span class="external"></span>class SampleClass(object):
<span class="external"> </span>pass <span class="external"> </span>pass
@ -1688,9 +1710,18 @@ from sound.effects import echo
<span class="external"> </span>"""Explicitly inherits from another class already.""" <span class="external"> </span>"""Explicitly inherits from another class already."""
<span class="external"></span> <span class="external"></span>
</PRE></DIV> </PRE></DIV>
<DIV class=""><PRE class="badcode">No: <span class="external"></span>class SampleClass:
<span class="external"> </span>pass
<span class="external"></span>class OuterClass:
<span class="external"> </span>class InnerClass:
<span class="external"> </span>pass
<span class="external"></span>
</PRE></DIV>
<p>Inheriting from <code>object</code> is needed to make properties work <p>Inheriting from <code>object</code> is needed to make properties work
properly, and it will protect your code from one particular potential properly, and it will protect your code from one particular potential
incompatibility with Python 3000. It also defines incompatibility with Python 3000. It also defines
special methods that implement the default semantics of objects including special methods that implement the default semantics of objects including
<code>__new__</code>, <code>__init__</code>, <code>__delattr__</code>, <code>__new__</code>, <code>__init__</code>, <code>__delattr__</code>,
@ -1710,12 +1741,13 @@ from sound.effects import echo
to decide between <code>+</code> and <code>%</code> though. to decide between <code>+</code> and <code>%</code> though.
</DIV> </DIV>
<DIV class=""><DIV class="stylepoint_body" name="Strings__body" id="Strings__body" style="display: none"> <DIV class=""><DIV class="stylepoint_body" name="Strings__body" id="Strings__body" style="display: none">
<DIV class=""><PRE class="badcode">No: <span class="external"></span>x = '%s%s' % (a, b) # use + in this case
<span class="external"></span>x = imperative + ', ' + expletive + '!'
<span class="external"></span>x = 'name: ' + name + '; score: ' + str(n)</PRE></DIV>
<DIV class=""><PRE>Yes: <span class="external"></span>x = a + b <DIV class=""><PRE>Yes: <span class="external"></span>x = a + b
<span class="external"></span>x = '%s, %s!' % (imperative, expletive) <span class="external"></span>x = '%s, %s!' % (imperative, expletive)
<span class="external"></span>x = 'name: %s; score: %d' % (name, n)</PRE></DIV> <span class="external"></span>x = 'name: %s; score: %d' % (name, n)</PRE></DIV>
<DIV class=""><PRE class="badcode">No: <span class="external"></span>x = '%s%s' % (a, b) # use + in this case
<span class="external"></span>x = imperative + ', ' + expletive + '!'
<span class="external"></span>x = 'name: ' + name + '; score: ' + str(n)</PRE></DIV>
<p> <p>
Avoid using the <code>+</code> and <code>+=</code> operators to Avoid using the <code>+</code> and <code>+=</code> operators to
@ -1726,15 +1758,15 @@ from sound.effects import echo
substring to a <code>cStringIO.StringIO</code> buffer). substring to a <code>cStringIO.StringIO</code> buffer).
</p> </p>
<DIV class=""><PRE class="badcode">No: <span class="external"></span>employee_table = '&lt;table&gt;'
<span class="external"></span>for last_name, first_name in employee_list:
<span class="external"> </span>employee_table += '&lt;tr&gt;&lt;td&gt;%s, %s&lt;/td&gt;&lt;/tr&gt;' % (last_name, first_name)
<span class="external"></span>employee_table += '&lt;/table&gt;'</PRE></DIV>
<DIV class=""><PRE>Yes: <span class="external"></span>items = ['&lt;table&gt;'] <DIV class=""><PRE>Yes: <span class="external"></span>items = ['&lt;table&gt;']
<span class="external"></span>for last_name, first_name in employee_list: <span class="external"></span>for last_name, first_name in employee_list:
<span class="external"> </span>items.append('&lt;tr&gt;&lt;td&gt;%s, %s&lt;/td&gt;&lt;/tr&gt;' % (last_name, first_name)) <span class="external"> </span>items.append('&lt;tr&gt;&lt;td&gt;%s, %s&lt;/td&gt;&lt;/tr&gt;' % (last_name, first_name))
<span class="external"></span>items.append('&lt;/table&gt;') <span class="external"></span>items.append('&lt;/table&gt;')
<span class="external"></span>employee_table = ''.join(items)</PRE></DIV> <span class="external"></span>employee_table = ''.join(items)</PRE></DIV>
<DIV class=""><PRE class="badcode">No: <span class="external"></span>employee_table = '&lt;table&gt;'
<span class="external"></span>for last_name, first_name in employee_list:
<span class="external"> </span>employee_table += '&lt;tr&gt;&lt;td&gt;%s, %s&lt;/td&gt;&lt;/tr&gt;' % (last_name, first_name)
<span class="external"></span>employee_table += '&lt;/table&gt;'</PRE></DIV>
<p> <p>
Use <code>"""</code> for multi-line strings rather than Use <code>"""</code> for multi-line strings rather than
@ -1743,14 +1775,88 @@ from sound.effects import echo
not flow with the indentation of the rest of the program: not flow with the indentation of the rest of the program:
</p> </p>
<DIV class=""><PRE class="badcode"> No<span class="external"></span>: <DIV class=""><PRE>Ye<span class="external"></span>s:
<span class="external"></span>print ("This is much nicer.\n"
<span class="external"></span> "Do it this way.\n")</PRE></DIV>
<DIV class=""><PRE class="badcode"> No<span class="external"></span>:
<span class="external"></span>print """This is pretty ugly. <span class="external"></span>print """This is pretty ugly.
Don'<span class="external"></span>t do this. Don'<span class="external"></span>t do this.
"""<span class="external"></span> """<span class="external"></span>
</PRE></DIV> </PRE></DIV>
<DIV class=""><PRE>Ye<span class="external"></span>s:
<span class="external"></span>print ("This is much nicer.\n" </DIV></DIV>
<span class="external"></span> "Do it this way.\n")</PRE></DIV> </DIV>
<DIV class="">
<H3><A name="Files_and_Sockets" id="Files_and_Sockets">Files and Sockets</A></H3>
<SPAN class="link_button" id="link-Files_and_Sockets__button" name="link-Files_and_Sockets__button"><A href="?showone=Files_and_Sockets#Files_and_Sockets">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Files_and_Sockets')" name="Files_and_Sockets__button" id="Files_and_Sockets__button"></SPAN>
<DIV style="display:inline;" class="">
Explicitly close files and sockets when done with them.
</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Files_and_Sockets__body" id="Files_and_Sockets__body" style="display: none">
<p>
Leaving files, sockets or other file-like objects open unnecessarily
has many downsides, including:
<ul>
<li>They may consume limited system resources, such as file
descriptors. Code that deals with many such objects may exhaust
those resources unnecessarily if they're not returned to the
system promptly after use.</li>
<li>Holding files open may prevent other actions being performed on
them, such as moves or deletion.</li>
<li>Files and sockets that are shared throughout a program may
inadvertantly be read from or written to after logically being
closed. If they are actually closed, attempts to read or write
from them will throw exceptions, making the problem known
sooner.</li>
</ul>
</p>
<p>
Furthermore, while files and sockets are automatically closed when the
file object is destructed, tying the life-time of the file object to
the state of the file is poor practice, for several reasons:
<ul>
<li>There are no guarantees as to when the runtime will actually run
the file's destructor. Different Python implementations use
different memory management techniques, such as delayed Garbage
Collection, which may increase the object's lifetime arbitrarily
and indefinitely.</li>
<li>Unexpected references to the file may keep it around longer than
intended (e.g. in tracebacks of exceptions, inside globals,
etc).</li>
</ul>
</p>
<p>
The preferred way to manage files is using the <a HREF="http://docs.python.org/reference/compound_stmts.html#the-with-statement">
"with" statement</a>:
</p>
<DIV class=""><PRE>
<span class="external"></span>with open("hello.txt") as hello_file:
<span class="external"> </span>for line in hello_file:
<span class="external"> </span>print line</PRE></DIV>
<p>
For file-like objects that do not support the "with" statement, use
contextlib.closing():
</p>
<DIV class=""><PRE>
<span class="external"></span>import contextlib
<span class="external"></span>with contextlib.closing(urllib.urlopen("http://www.python.org/")) as front_page:
<span class="external"> </span>for line in front_page:
<span class="external"> </span>print line</PRE></DIV>
<p>
Legacy AppEngine code using Python 2.5 may enable the "with" statement
using "from __future__ import with_statement".
</p>
</DIV></DIV> </DIV></DIV>
</DIV> </DIV>
<DIV class=""> <DIV class="">
@ -1880,8 +1986,8 @@ Don'<span class="external"></span>t do this.
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Access_Control')" name="Access_Control__button" id="Access_Control__button"></SPAN> </A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Access_Control')" name="Access_Control__button" id="Access_Control__button"></SPAN>
<DIV style="display:inline;" class=""> <DIV style="display:inline;" class="">
If an accessor function would be trivial you should use public variables If an accessor function would be trivial you should use public variables
instead of accessor functions to avoid the extra cost of function instead of accessor functions to avoid the extra cost of function
calls in Python. When more functionality is added you can use calls in Python. When more functionality is added you can use
<code>property</code> to keep the syntax consistent. <code>property</code> to keep the syntax consistent.
</DIV> </DIV>
<DIV class=""><DIV class="stylepoint_body" name="Access_Control__body" id="Access_Control__body" style="display: none"> <DIV class=""><DIV class="stylepoint_body" name="Access_Control__body" id="Access_Control__body" style="display: none">
@ -1916,7 +2022,7 @@ Don'<span class="external"></span>t do this.
<li>single character names except for counters or iterators</li> <li>single character names except for counters or iterators</li>
<li>dashes (<code>-</code>) in any package/module name</li> <li>dashes (<code>-</code>) in any package/module name</li>
<li> <li>
<code>__double_leading_and_trailing_underscore__</code> names <code>__double_leading_and_trailing_underscore__</code> names
(reserved by Python)</li> (reserved by Python)</li>
</ul> </ul>
@ -1936,14 +2042,14 @@ Don'<span class="external"></span>t do this.
effectively serves to make the variable or method private to its class effectively serves to make the variable or method private to its class
(using name mangling).</li> (using name mangling).</li>
<li> <li>
Place related classes and top-level functions together in a Place related classes and top-level functions together in a
module. Unlike Java, module. Unlike Java,
there is no need to limit yourself to one class per module.</li> there is no need to limit yourself to one class per module.</li>
<li> <li>
Use CapWords for class names, but lower_with_under.py for module names. Use CapWords for class names, but lower_with_under.py for module names.
Although there are many existing modules named CapWords.py, this is now Although there are many existing modules named CapWords.py, this is now
discouraged because it's confusing when the module happens to be discouraged because it's confusing when the module happens to be
named after a class. ("wait -- did I write named after a class. ("wait -- did I write
<code>import StringIO</code> or <code>from StringIO import <code>import StringIO</code> or <code>from StringIO import
StringIO</code>?")</li> StringIO</code>?")</li>
</ul> </ul>
@ -2045,9 +2151,9 @@ Don'<span class="external"></span>t do this.
link link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Main')" name="Main__button" id="Main__button"></SPAN> </A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Main')" name="Main__button" id="Main__button"></SPAN>
<DIV style="display:inline;" class=""> <DIV style="display:inline;" class="">
Even a file meant to be used as a script should be importable and a Even a file meant to be used as a script should be importable and a
mere import should not have the side effect of executing the script's mere import should not have the side effect of executing the script's
main functionality. The main functionality should be in a main() main functionality. The main functionality should be in a main()
function. function.
</DIV> </DIV>
<DIV class=""><DIV class="stylepoint_body" name="Main__body" id="Main__body" style="display: none"> <DIV class=""><DIV class="stylepoint_body" name="Main__body" id="Main__body" style="display: none">
@ -2057,7 +2163,7 @@ Don'<span class="external"></span>t do this.
require modules to be importable. Your code should always check require modules to be importable. Your code should always check
<code>if __name__ == '__main__'</code> before executing your <code>if __name__ == '__main__'</code> before executing your
main program so that the main program is not executed when the main program so that the main program is not executed when the
module is imported. module is imported.
</p> </p>
@ -2112,7 +2218,7 @@ Don'<span class="external"></span>t do this.
<p align="right"> <p align="right">
Revision 2.29 Revision 2.39
</p> </p>