Update C++ style guide to 3.146:

- Make the messaging on DISALLOW_EVIL_CONSTRUCTORS more clear that we should
   not be rewriting old code but should simply prefer DISALLOW_COPY_AND_ASSIGN
   on new code.
 - s/Initializer Lists/Constructor Initializer Lists/ since people search for
   this based on knowing it's part of the constructor, but forget the precise
   name.
 - Allow data members in a test fixture to be private.
 - Loosen restrictions on globals.
 - Add explicit guideline for nested namespace formatting.
 - Strengthen the prohibition against operator overloading for operator&.
 - Add recommendation for "_" over "-" in file names.
 - Revise the "Copy Constructors" section for brevity and clarity.  Emphasize
   preference for standard over nonstandard copy operations.
 - Weaken the wording at the top of the "Doing Work in Constructors" section,
   making it clear that Init() methods are not absolutely required for
   non-trivial initialization.
 - Fix minor typos and grammatical errors.

Update Objective-C style guide to 2.14:
 - Add the Rule of Four for indenting parameters.  Allow either of two forms
   for formatting methods with short first keywords.
 - Update the guidance on BOOL vs. bool.
 - Whitespace cleanup.

Update Python style guide to 2.14:
 - Consolidate discussion of the string module, apply, map, filter, and reduce
   into a single section.
 - Make it explicit that functions and classes can be nested inside methods.
This commit is contained in:
mmentovai 2009-10-23 21:01:49 +00:00
parent 2df72b34d0
commit f7facf9026
3 changed files with 274 additions and 218 deletions

View File

@ -4,7 +4,7 @@
<p align="right">
Revision 3.133
Revision 3.146
</p>
@ -96,6 +96,7 @@ Tashana Landray
reader is familiar with the language.
</p>
</CATEGORY>
</OVERVIEW>
@ -750,34 +751,42 @@ Tashana Landray
</SUMMARY>
<BODY>
<p>
Objects with static storage duration, including global variables,
Objects with static storage duration, including global variables,
static variables, static class member variables, and function static
variables, must be Plain Old Data (POD): only ints, chars, floats, and
void, and arrays of/structs of/pointers to POD. Static variables must
not be initialized with the result of a function; and non-const static
variables must not be used in threaded code.
variables, must be Plain Old Data (POD): only ints, chars, floats, or
pointers, or arrays/structs of POD.
</p>
<p>
The order in which class constructors, destructors, and initializers for
The order in which class constructors and initializers for
static variables are called is only partially specified in C++ and can
even change from build to build, which can cause bugs that are difficult
to find. For example, at program-end time a static variable might have
to find. Therefore in addition to banning globals of class type, we do
not allow static POD variables to be initialized with the result of a
function, unless that function (such as getenv(), or getpid()) does not
itself depend on any other globals.
</p>
<p>
Likewise, the order in which destructors are called is defined to be the
reverse of the order in which the constructors were called. Since
constructor order is indeterminate, so is destructor order.
For example, at program-end time a static variable might have
been destroyed, but code still running -- perhaps in another thread --
tries to access it and fails.
tries to access it and fails. Or the destructor for a static 'string'
variable might be run prior to the destructor for another variable that
contains a reference to that string.
</p>
<p>
As a result we only allow static variables to contain POD data. This
rule completely disallows <code>vector</code> (use C arrays instead),
<code>string</code> (use <code>const char*</code>), or anything that
contains or points to any class instance in any way, from ever being a
part of a static variable. For similar reasons, we don't allow static
variables to be initialized with the result of a function call.
rule completely disallows <code>vector</code> (use C arrays instead), or
<code>string</code> (use <code>const char []</code>).
</p>
<p>
If you need a static or global variable of a class type, consider
initializing a pointer which you never free from your main() function
or from pthread_once().
initializing a pointer (which will never be freed), from either your
main() function or from pthread_once(). Note that this must be a raw
pointer, not a "smart" pointer, since the smart pointer's destructor
will have the order-of-destructor issue that we are trying to avoid.
</p>
@ -792,9 +801,9 @@ Tashana Landray
<STYLEPOINT title="Doing Work in Constructors">
<SUMMARY>
Do only trivial initialization in a constructor. If at all
possible, use an <code>Init()</code> method for non-trivial
initialization.
In general, constructors should merely set member variables to their
initial values. Any complex initialization should go in an explicit
<code>Init()</code> method.
</SUMMARY>
<BODY>
<DEFINITION>
@ -835,9 +844,9 @@ Tashana Landray
</CONS>
<DECISION>
If your object requires non-trivial initialization, consider
having an explicit <code>Init()</code> method and/or adding a
member flag that indicates whether the object was successfully
initialized.
having an explicit <code>Init()</code> method. In particular,
constructors should not call virtual functions, attempt to raise
errors, access potentially uninitialized global variables, etc.
</DECISION>
</BODY>
</STYLEPOINT>
@ -863,7 +872,7 @@ Tashana Landray
</CONS>
<DECISION>
<p>
If your class defines member variables has no other
If your class defines member variables and has no other
constructors you must define a default constructor (one that
takes no arguments). It should preferably initialize the
object in such a way that its internal state is consistent
@ -933,19 +942,22 @@ Tashana Landray
<STYLEPOINT title="Copy Constructors">
<SUMMARY>
Use copy constructors only when your code needs to copy a class;
most do not need to be copied and so should use
<code>DISALLOW_COPY_AND_ASSIGN</code>.
Provide a copy constructor and assignment operator only when necessary.
Otherwise, disable them with <code>DISALLOW_COPY_AND_ASSIGN</code>.
</SUMMARY>
<BODY>
<DEFINITION>
The copy constructor is used when copying one object into a
new one (especially when passing objects by value).
The copy constructor and assignment operator are used to create copies
of objects. The copy constructor is implicitly invoked by the
compiler in some situations, e.g. passing objects by value.
</DEFINITION>
<PROS>
Copy constructors make it easy to copy objects. STL
containers require that all contents be copyable and
assignable.
assignable. Copy constructors can be more efficient than
<code>CopyFrom()</code>-style workarounds because they combine
construction with copying, the compiler can elide them in some
contexts, and they make it easier to avoid heap allocation.
</PROS>
<CONS>
Implicit copying of objects in C++ is a rich source of bugs
@ -956,19 +968,35 @@ Tashana Landray
</CONS>
<DECISION>
<p>
Most classes do not need to be copyable, and should not have a
copy constructor or an assignment operator. Unfortunately, the
compiler generates these for you, and makes them public, if
you do not declare them yourself.
Few classes need to be copyable. Most should have neither a
copy constructor nor an assignment operator. In many situations,
a pointer or reference will work just as well as a copied value,
with better performance. For example, you can pass function
parameters by reference or pointer instead of by value, and you can
store pointers rather than objects in an STL container.
</p>
<p>
Consider adding dummy declarations for the copy constructor and
assignment operator in the class' <code>private:</code> section,
without providing definitions. With these dummy routines marked
private, a compilation error will be raised if other code
attempts to use them. For convenience, a
<code>DISALLOW_COPY_AND_ASSIGN</code> macro can be used:
If your class needs to be copyable, prefer providing a copy method,
such as <code>CopyFrom()</code> or <code>Clone()</code>, rather than
a copy constructor, because such methods cannot be invoked
implicitly. If a copy method is insufficient in your situation
(e.g. for performance reasons, or because your class needs to be
stored by value in an STL container), provide both a copy
constructor and assignment operator.
</p>
<p>
If your class does not need a copy constructor or assignment
operator, you must explicitly disable them.
To do so, add dummy declarations for the copy constructor and
assignment operator in the <code>private:</code> section of your
class, but do not provide any corresponding definition (so that
any attempt to use them results in a link error).
</p>
<p>
For convenience, a <code>DISALLOW_COPY_AND_ASSIGN</code> macro
can be used:
</p>
<CODE_SNIPPET>
// A macro to disallow the copy constructor and operator= functions
@ -991,23 +1019,6 @@ Tashana Landray
};
</CODE_SNIPPET>
<p>
In almost all cases your class should use the
<code>DISALLOW_COPY_AND_ASSIGN</code>
macro as described above. If your class is one of the rare
classes that does need to be copyable, you should document why
this is so in the header file for that class, and you should
define the copy constructor and assignment operator
appropriately. Remember to check for self-assignment in
<code>operator=</code>.
</p>
<p>
You may be tempted to make your class copyable so that you
can use it as a value in STL containers. In almost all such
cases you should really put <em>pointers</em> to your
objects in the STL container. You may also want to consider
using
<code>std::tr1::shared_ptr</code>.
</p>
</DECISION>
@ -1107,7 +1118,7 @@ Tashana Landray
<p>
Limit the use of <code>protected</code> to those member
functions that might need to be accessed from subclasses.
Note that <a href="#Access_Control">data members must always
Note that <a href="#Access_Control">data members should
be private</a>.
</p>
<p>
@ -1256,16 +1267,18 @@ Tashana Landray
</li>
</ul>
Overloading also has surprising ramifications. For instance,
you can't forward declare classes that overload
<code>operator&amp;</code>.
if a class overloads unary <code>operator&amp;</code>, it
cannot safely be forward-declared.
</CONS>
<DECISION>
<p>
In general, do not overload operators. The assignment operator
(<code>operator=</code>), in particular, is insidious and
should be avoided. You can define functions like
<code>Equals()</code> and <code>CopyFrom()</code> if you need
them.
<code>Equals()</code> and <code>CopyFrom()</code> if you
need them. Likewise, avoid the dangerous
unary <code>operator&amp;</code> at all costs, if there's
any possibility the class might be forward-declared.
</p>
<p>
However, there may be rare cases where you need to overload
@ -1296,10 +1309,15 @@ Tashana Landray
<STYLEPOINT title="Access Control">
<SUMMARY>
Make <em>all</em> data members <code>private</code>, and provide
access to them through accessor functions as needed. Typically
a variable would be called <code>foo_</code> and the accessor
function <code>foo()</code>. You may also want a mutator
function <code>set_foo()</code>.
access to them through accessor functions as needed (for
technical reasons, we allow data members of a test fixture class
to be <code>protected</code> when using
<A HREF="http://code.google.com/p/googletest/">
Google Test</A>). Typically a variable would be
called <code>foo_</code> and the accessor function
<code>foo()</code>. You may also want a mutator function
<code>set_foo()</code>.
</SUMMARY>
<BODY>
<p>
@ -2603,7 +2621,7 @@ Tashana Landray
convention that your
project
uses.
uses. If there is no consistent local pattern to follow, prefer "_".
</SUMMARY>
<BODY>
<p>
@ -2978,8 +2996,8 @@ Tashana Landray
<SUBSECTION title="File Contents">
<p>
Every file should have a comment at the top, below the
and author line, that describes the contents of the file.
Every file should have a comment at the top, below the copyright
notice and author line, that describes the contents of the file.
</p>
<p>
Generally a <code>.h</code> file will describe the classes
@ -4003,7 +4021,7 @@ Tashana Landray
</BODY>
</STYLEPOINT>
<STYLEPOINT title="Initializer Lists">
<STYLEPOINT title="Constructor Initializer Lists">
<SUMMARY>
Constructor initializer lists can be all on one line or with
subsequent lines indented four spaces.
@ -4064,6 +4082,13 @@ Tashana Landray
} // namespace
</BAD_CODE_SNIPPET>
<p>
When declaring nested namespaces, put each namespace on its own line.
</p>
<CODE_SNIPPET>
namespace foo {
namespace bar {
</CODE_SNIPPET>
</BODY>
</STYLEPOINT>
@ -4352,7 +4377,7 @@ Tashana Landray
<HR/>
<p align="right">
Revision 3.133
Revision 3.146
</p>

View File

@ -4,7 +4,7 @@
<p align="right">
Revision 2.12
Revision 2.14
</p>
@ -16,7 +16,7 @@ Revision 2.12
Dave MacLachlan
</address>
</div>
<OVERVIEW>
<CATEGORY title="Important Note">
@ -94,7 +94,7 @@ Revision 2.12
<p>
Google has already released open-source code that conforms to these
guidelines as part of the
guidelines as part of the
<a href="http://code.google.com/p/google-toolbox-for-mac/">
Google Toolbox for Mac project
</a>
@ -102,13 +102,13 @@ Revision 2.12
Code meant to be shared across different projects is a good candidate to
be included in this repository.
</p>
<p>
Note that this guide is not an Objective-C tutorial. We assume that the
reader is familiar with the language. If you are new to Objective-C or
need a refresher, please read
need a refresher, please read
<a href="http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/index.html">
The Objective-C Programming Language
</a>.
@ -117,7 +117,7 @@ Revision 2.12
</OVERVIEW>
<CATEGORY title="Example">
<p>
They say an example is worth a thousand words so let's start off with an
example that should give you a feel for the style, spacing, naming, etc.
@ -135,9 +135,9 @@ Revision 2.12
// Created by Greg Miller on 6/13/08.
// Copyright 2008 Google, Inc. All rights reserved.
//
#import &lt;Foundation/Foundation.h&gt;
// A sample class demonstrating good Objective-C style. All interfaces,
// categories, and protocols (read: all top-level declarations in a header)
// MUST be commented. Comments must also be adjacent to the object they're
@ -149,32 +149,32 @@ Revision 2.12
NSString *foo_;
NSString *bar_;
}
// Returns an autoreleased instance of GMFoo. See -initWithString: for details
// about the argument.
+ (id)fooWithString:(NSString *)string;
// Designated initializer. |string| will be copied and assigned to |foo_|.
- (id)initWithString:(NSString *)string;
// Gets and sets the string for |foo_|.
- (NSString *)foo;
- (void)setFoo:(NSString *)newFoo;
// Does some work on |blah| and returns YES if the work was completed
// successfuly, and NO otherwise.
- (BOOL)doWorkWithString:(NSString *)blah;
@end
</CODE_SNIPPET>
<p>
An example source file, demonstating the correct commenting and spacing
for the <code>@implementation</code> of an interface. It also includes the
reference implementations for important methods like getters and setters,
<code>init</code>, and <code>dealloc</code>.
</p>
<CODE_SNIPPET>
//
// GTMFoo.m
@ -183,49 +183,49 @@ Revision 2.12
// Created by Greg Miller on 6/13/08.
// Copyright 2008 Google, Inc. All rights reserved.
//
#import "GTMFoo.h"
@implementation GTMFoo
+ (id)fooWithString:(NSString *)string {
return [[[self alloc] initWithString:string] autorelease];
}
// Must always override super's designated initializer.
- (id)init {
return [self initWithString:nil];
}
- (id)initWithString:(NSString *)string {
if ((self = [super init])) {
foo_ = [string copy];
bar_ = [[NSString alloc] initWithFormat:@"hi %d", 3];
}
return self;
return self;
}
- (void)dealloc {
[foo_ release];
[bar_ release];
[super dealloc];
}
- (NSString *)foo {
return foo_;
}
- (void)setFoo:(NSString *)newFoo {
[foo_ autorelease];
foo_ = [newFoo copy];
foo_ = [newFoo copy];
}
- (BOOL)doWorkWithString:(NSString *)blah {
// ...
return NO;
}
@end
</CODE_SNIPPET>
@ -291,7 +291,7 @@ Revision 2.12
</p>
<p>
If you have too many parameters to fit on one line, giving each its
own line is preferred. If multiple lines are used, align each using
own line is preferred. If multiple lines are used, align each using
the <code>:</code> before the parameter.
</p>
<CODE_SNIPPET>
@ -301,9 +301,33 @@ Revision 2.12
...
}
</CODE_SNIPPET>
<p>
When the first keyword is shorter than the others, indent the later
lines by at least four spaces. You can do this by making keywords
line up vertically, not aligning colons:
</p>
<CODE_SNIPPET>
- (void)short:(GTMFoo *)theFoo
longKeyword:(NSRect)theRect
evenLongerKeyword:(float)theInterval {
...
}
</CODE_SNIPPET>
<p>
Or you may align all colons, indenting the first keyword if needed,
as below. In editing existing source, use the convention in that
file.
</p>
<CODE_SNIPPET>
- (void) short:(GTMFoo *)theFoo
longKeyword:(NSRect)theRect
evenLongerKeyword:(float)theInterval {
...
}
</CODE_SNIPPET>
</BODY>
</STYLEPOINT>
<STYLEPOINT title="@public and @private">
<SUMMARY>
The <code>@public</code> and <code>@private</code> access modifiers
@ -322,7 +346,7 @@ Revision 2.12
...
}
@end
</CODE_SNIPPET>
</CODE_SNIPPET>
</BODY>
</STYLEPOINT>
@ -352,11 +376,11 @@ Revision 2.12
</CODE_SNIPPET>
</BODY>
</STYLEPOINT>
</CATEGORY>
<CATEGORY title="Naming">
<p>
Naming rules are very important in maintainable code. Objective-C method
names tend to be very long, but this has the benefit that a block of code
@ -368,6 +392,12 @@ Revision 2.12
in variable names, whereas this guide recommends the use of intercaps,
which is standard in the Objective-C community.
</p>
<p>
Any class, category, method, or variable name may use all capitals for
<a href="http://en.wikipedia.org/wiki/Initialism">initialisms</a>
within the name. This follows Apple's standard of using all capitals
within a name for initialisms such as URL, TIFF, and EXIF.
</p>
<p>
When writing Objective-C++, however, things are not so cut and dry. Many
projects need to implement cross-platform C++ APIs with some Objective-C
@ -440,7 +470,7 @@ Revision 2.12
</p>
<CODE_SNIPPET>
// file: cross_platform_header.h
class CrossPlatformAPI {
public:
...
@ -448,10 +478,10 @@ Revision 2.12
private:
int an_instance_var_;
};
// file: mac_implementation.mm
#include "cross_platform_header.h"
// A typical Objective-C class, using Objective-C naming.
@interface MyDelegate : NSObject {
@private
@ -468,7 +498,7 @@ Revision 2.12
NSLog(@"%@", tempString);
}
@end
// The platform-specific implementation of the C++ class, using
// C++ naming.
int CrossPlatformAPI::DoSomethingPlatformSpecific() {
@ -479,7 +509,7 @@ Revision 2.12
</CODE_SNIPPET>
</BODY>
</STYLEPOINT>
<STYLEPOINT title="Class Names">
<SUMMARY>
Class names (along with category and protocol names) should start as
@ -502,7 +532,7 @@ Revision 2.12
Category names should start with a 2 or 3 character prefix
identifying the category as part of a project or open for general
use. The category name should incorporate the name of the class it's
extending.
extending.
</SUMMARY>
<BODY>
<p>
@ -520,7 +550,7 @@ Revision 2.12
</p>
</BODY>
</STYLEPOINT>
<STYLEPOINT title="Objective-C Method Names">
<SUMMARY>
Method names should start as lowercase and then use mixed case.
@ -571,36 +601,36 @@ Revision 2.12
code immediately understandable by a new reader. For example:
</p>
<BAD_CODE_SNIPPET>
int w;
int nerr;
int nCompConns;
int w;
int nerr;
int nCompConns;
tix = [[NSMutableArray alloc] init];
obj = [someObject object];
p = [network port];
</BAD_CODE_SNIPPET>
<CODE_SNIPPET>
int numErrors;
int numCompletedConnections;
int numErrors;
int numCompletedConnections;
tickets = [[NSMutableArray alloc] init];
userInfo = [someObject object];
port = [network port];
</CODE_SNIPPET>
</SUBSECTION>
<SUBSECTION title="Instance Variables">
<p>
Instance variables are mixed case and should be suffixed with a
trailing underscore, e.g. <var>usernameTextField_</var>. However,
we permit an exception when binding to a member variable using
KVO/KVC and Objective-C 2.0 cannot be used (due to OS release
KVO/KVC and Objective-C 2.0 cannot be used (due to OS release
constraints). In this case, it is acceptable to prefix the variable
with an underscore, per Apple's accepted practices for key/value
with an underscore, per Apple's accepted practices for key/value
naming. If Objective-C 2.0 can be used, <code>@property</code> and
<code>@synthesize</code> provide a solution that conforms to the
naming guidelines.
</p>
</SUBSECTION>
<SUBSECTION title="Constants">
<p>
Constant names (#defines, enums, const local variables, etc.) should
@ -729,7 +759,7 @@ Revision 2.12
<STYLEPOINT title="Object Ownership">
<SUMMARY>
Make the pointer ownership model as explicit as possible when it falls
outside the most common Objective-C usage idioms.
outside the most common Objective-C usage idioms.
</SUMMARY>
<BODY>
<p>
@ -772,7 +802,7 @@ Revision 2.12
</p>
</BODY>
</STYLEPOINT>
</CATEGORY>
<CATEGORY title="Cocoa and Objective-C Features">
@ -794,7 +824,7 @@ Revision 2.12
</CODE_SNIPPET>
</BODY>
</STYLEPOINT>
<STYLEPOINT title="Identify Designated Initializer">
<SUMMARY>
Comment and clearly identify your designated initializer.
@ -867,7 +897,7 @@ Revision 2.12
@implementation GTMFoo(PrivateDelegateHandling)
...
- (NSString *)doSomethingWithDelegate {
// Implement this method
// Implement this method
}
...
@end
@ -883,7 +913,7 @@ Revision 2.12
<p>
If you are using Objective-C 2.0, you should instead declare your
private category using a <a href="http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Articles/chapter_4_section_5.html#">class
extension</a>, for example:
extension</a>, for example:
</p>
<CODE_SNIPPET>
@interface GMFoo () { ... }
@ -986,7 +1016,7 @@ Revision 2.12
</BAD_CODE_SNIPPET>
</BODY>
</STYLEPOINT>
<STYLEPOINT title="Prefer To autorelease At Time of Creation">
<SUMMARY>
When creating new temporary objects, <code>autorelease</code> them on
@ -1029,7 +1059,7 @@ Revision 2.12
<CODE_SNIPPET>
- (void)setFoo:(GMFoo *)aFoo {
[foo_ autorelease]; // Won't dealloc if |foo_| == |aFoo|
foo_ = [aFoo retain];
foo_ = [aFoo retain];
}
</CODE_SNIPPET>
</BODY>
@ -1091,7 +1121,7 @@ Revision 2.12
void foo() {
exceptiontest a;
NSException *exception = [NSException exceptionWithName:@"foo"
reason:@"bar"
reason:@"bar"
userInfo:nil];
@throw exception;
}
@ -1155,30 +1185,58 @@ Revision 2.12
<STYLEPOINT title="BOOL Pitfalls">
<SUMMARY>
Be careful with <code>BOOL</code> return values and mixing
<code>bool</code> with <code>BOOL</code>. Avoid comparing directly
with <code>YES</code>.
Be careful when converting general integral values to <code>BOOL</code>.
Avoid comparing directly with <code>YES</code>.
</SUMMARY>
<BODY>
<p>
Only use the constants YES and NO for <code>BOOL</code> return values
and assignments. Common mistakes include casting an array's size or
a pointer value as a BOOL, which depending on the value of the last
byte, could still result in a NO value.
<code>BOOL</code> is defined as an unsigned char in Objective-C which
means that it can have values other than <code>YES</code> (1) and
<code>NO</code> (0). Do not cast or convert general integral values
directly to <code>BOOL</code>. Common mistakes include casting or
converting an array's size, a pointer value, or the result of a bitwise
logic operation to a <code>BOOL</code> which, depending on the value of
the last byte of the integral result, could still result in a
<code>NO</code> value. When converting a general integral value to a
<code>BOOL</code> use ternery operators to return a <code>YES</code>
or <code>NO</code> value.
</p>
<p>
Also be careful when interoperating with C++ and its <code>bool</code>
type. Don't just assume that <code>YES</code> and <code>NO</code>
map directly to <code>true</code> and <code>false</code>. You can use
the ternary operator to succinctly map between them.
You can safely interchange and convert <code>BOOL</code>,
<code>_Bool</code> and <code>bool</code> (see C++ Std 4.7.4, 4.12 and
C99 Std 6.3.1.2). You cannot safely interchange <code>BOOL</code> and
<code>Boolean</code> so treat <code>Booleans</code> as a general
integral value as discussed above. Only use <code>BOOL</code> in
Objective C method signatures.
</p>
<p>
Using logical operators (<code>&amp;&amp;</code>, <code>||</code> and
<code>!</code>) with <code>BOOL</code> is also valid and will return
values that can be safely converted to <code>BOOL</code> without the
need for a ternery operator.
</p>
<BAD_CODE_SNIPPET>
- (BOOL)isBold {
return [self fontTraits] &amp; NSFontBoldTrait;
}
- (BOOL)isValid {
return [self stringValue];
}
</BAD_CODE_SNIPPET>
<CODE_SNIPPET>
bool b = myBOOL ? true : false; // to go one way...
myBOOL = b ? YES : NO; // ... or the other
- (BOOL)isBold {
return ([self fontTraits] &amp; NSFontBoldTrait) ? YES : NO;
}
- (BOOL)isValid {
return [self stringValue] != nil;
}
- (BOOL)isEnabled {
return [self isValid] &amp;&amp; [self isBold];
}
</CODE_SNIPPET>
<p>
Finally, don't directly compare <code>BOOL</code> variables directly
with <code>YES</code>. Not only is is harder to read for those
Also, don't directly compare <code>BOOL</code> variables directly
with <code>YES</code>. Not only is it harder to read for those
well-versed in C, the first point above demonstrates that return
values may not always be what you expect.
</p>
@ -1192,9 +1250,10 @@ Revision 2.12
if (great)
// ...be great!
</CODE_SNIPPET>
</BODY>
</STYLEPOINT>
<STYLEPOINT title="Properties">
<SUMMARY>
Properties in general are allowed with the following caveat: properties
@ -1202,7 +1261,7 @@ Revision 2.12
on the iPhone and MacOS X 10.5 (Leopard) and higher. Dot notation to
access properties is not allowed.
</SUMMARY>
<BODY>
<BODY>
<SUBSECTION title="Naming">
<p>
A property's associated instance variable's name must conform to the
@ -1212,7 +1271,7 @@ Revision 2.12
<p>
Use the @synthesize directive to rename the property correctly.
</p>
<CODE_SNIPPET>
@interface MyClass : NSObject {
@private
@ -1220,7 +1279,7 @@ Revision 2.12
}
@property(copy, nonatomic) NSString *name;
@end
@implementation MyClass
@synthesize name = name_;
@end
@ -1231,7 +1290,7 @@ Revision 2.12
A property's declaration must come immediately after the instance
variable block of a class interface. A property's definition must
come immediately after the <code>@implementation</code> block in a
class definition. They are indented at the same level as the
class definition. They are indented at the same level as the
<code>@interface</code> or <code>@implementation</code> statements
that they are enclosed in.
</p>
@ -1242,7 +1301,7 @@ Revision 2.12
}
@property(copy, nonatomic) NSString *name;
@end
@implementation MyClass
@synthesize name = name_;
- (id)init {
@ -1265,7 +1324,7 @@ Revision 2.12
<SUBSECTION title="Never synthesize CFType properties">
<p>
CFTypes should always have the <code>@dynamic</code> implementation
directive.
directive.
</p>
<p>
Since CFTypes can't have the <code>retain</code> property
@ -1290,7 +1349,7 @@ Revision 2.12
@interface MyClass : NSObject
@property(readonly) NSString *name;
@end
@implementation MyClass
.
.
@ -1304,7 +1363,7 @@ Revision 2.12
@interface MyClass : NSObject
@property(readonly) NSString *name;
@end
@implementation MyClass
@dynamic name;
.
@ -1333,12 +1392,12 @@ Revision 2.12
<li>
Dot notation is purely syntactic sugar for standard method calls,
whose readability gains are debatable. It just gives you another
way to make method calls.
way to make method calls.
</li>
<li>
It obscures the type that you are dereferencing. When one sees:
<code>[foo setBar:1]</code> it is immediately clear that you are
working with an Objective-C object. When one sees
working with an Objective-C object. When one sees
<code>foo.bar = 1</code> it is not clear if foo is an object, or
a struct/union/C++ class.
</li>
@ -1366,7 +1425,7 @@ Revision 2.12
<CATEGORY title="Cocoa Patterns">
<STYLEPOINT title="Delegate Pattern">
<SUMMARY>
Delegate objects should not be retained.
@ -1430,7 +1489,7 @@ Revision 2.12
<HR/>
<p align="right">
Revision 2.12
Revision 2.14
</p>

View File

@ -1,5 +1,4 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/REC-html4/strict.dtd">
<HTML>
<HTML xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcq="http://purl.org/dc/qualifiers/1.0/" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE>Google Python Style Guide</TITLE>
@ -95,7 +94,7 @@
<H1>Google Python Style Guide</H1>
<p align="right">
Revision 2.12
Revision 2.14
</p>
<address>
@ -124,7 +123,7 @@
<TR valign="top" class="">
<TD><DIV class="toc_category"><A href="#Python_Language_Rules">Python Language Rules</A></DIV></TD>
<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="#Using_apply,_filter,_map,_reduce">Using apply, filter, map, reduce</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="#String_Methods">String Methods</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="#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 valign="top" class="">
<TD><DIV class="toc_category"><A href="#Python_Style_Rules">Python Style Rules</A></DIV></TD>
@ -438,9 +437,9 @@ from sound.effects import echo
</A></SPAN>
<P class="">
<SPAN class="stylepoint_section">Definition: </SPAN>
A class can be defined inside of a function or class. A function
can be defined inside a function. Nested functions have read-only
access to variables defined in enclosing scopes.
A class can be defined inside of a method, function, or class. A
function can be defined inside a method or function. Nested functions
have read-only access to variables defined in enclosing scopes.
</P>
<P class="">
<SPAN class="stylepoint_section">Pros: </SPAN>
@ -601,39 +600,6 @@ from sound.effects import echo
</P>
</SPAN></SPAN>
</SPAN>
<SPAN class=""><H3><A name="Using_apply,_filter,_map,_reduce" id="Using_apply,_filter,_map,_reduce">Using apply, filter, map, reduce</A></H3>
<SPAN class="showhide_button" onclick="javascript:ShowHideByName('Using_apply,_filter,_map,_reduce__body','Using_apply,_filter,_map,_reduce__button')" name="Using_apply,_filter,_map,_reduce__button" id="Using_apply,_filter,_map,_reduce__button"></SPAN>
<SPAN class="">
Avoid in favor of list comprehensions and for-loops.
</SPAN>
<SPAN class=""><BR><SPAN class="stylepoint_body" name="Using_apply,_filter,_map,_reduce__body" id="Using_apply,_filter,_map,_reduce__body" style="display: none"><SPAN class="link_button"><A href="?showone=Using_apply,_filter,_map,_reduce#Using_apply,_filter,_map,_reduce">
link
</A></SPAN>
<P class="">
<SPAN class="stylepoint_section">Definition: </SPAN> Built-in functions useful for manipulating
lists. Commonly used in conjunction with <code>lambda</code>
functions.
</P>
<P class="">
<SPAN class="stylepoint_section">Pros: </SPAN>
Code is compact.
</P>
<P class="">
<SPAN class="stylepoint_section">Cons: </SPAN>
Higher-order functional programming tends to be harder to understand.
</P>
<P class="">
<SPAN class="stylepoint_section">Decision: </SPAN> Use list comprehensions when possible and limit
use to simple code and one-liners. In general, if such code
grows longer than 6080 chars or if it uses
multi-level function calls (e.g., <code>map(lambda x: x[1],
filter(…))</code>), that's a signal that you are better
off writing a regular loop instead. Compare:
<SPAN class=""><PRE>Yes: <span class="external"></span>list comprehensions: [x[1] for x in my_list if x[2] == 5]</PRE></SPAN>
<SPAN class=""><PRE class="badcode">No: <span class="external"></span>map/filter: map(lambda x: x[1], filter(lambda x: x[2] == 5, my_list))</PRE></SPAN>
</P>
</SPAN></SPAN>
</SPAN>
<SPAN class=""><H3><A name="Lambda_Functions" id="Lambda_Functions">Lambda Functions</A></H3>
<SPAN class="showhide_button" onclick="javascript:ShowHideByName('Lambda_Functions__body','Lambda_Functions__button')" name="Lambda_Functions__button" id="Lambda_Functions__button"></SPAN>
<SPAN class="">
@ -720,8 +686,8 @@ from sound.effects import echo
<SPAN class=""><PRE class="badcode">No: <span class="external"></span>def foo(a, b=[]):
<span class="external"> </span>...</PRE></SPAN>
<p>
Calling code must use named values for the default args. This
helps document the code somewhat and helps prevent and detect
Calling code must use named values for arguments with a default value.
This helps document the code somewhat and helps prevent and detect
interface breakage when more arguments are added.
</p>
<SPAN class=""><PRE>
@ -912,32 +878,38 @@ from sound.effects import echo
</P>
</SPAN></SPAN>
</SPAN>
<SPAN class=""><H3><A name="String_Methods" id="String_Methods">String Methods</A></H3>
<SPAN class="showhide_button" onclick="javascript:ShowHideByName('String_Methods__body','String_Methods__button')" name="String_Methods__button" id="String_Methods__button"></SPAN>
<SPAN class=""><H3><A name="Deprecated_Language_Features" id="Deprecated_Language_Features">Deprecated Language Features</A></H3>
<SPAN class="showhide_button" onclick="javascript:ShowHideByName('Deprecated_Language_Features__body','Deprecated_Language_Features__button')" name="Deprecated_Language_Features__button" id="Deprecated_Language_Features__button"></SPAN>
<SPAN class="">
Use string methods instead of the <code>string</code> module where
possible.
Use string methods instead of the <code>string</code> module
where possible. Use function call syntax instead
of <code>apply</code>. Use list comprehensions
and <code>for</code> loops instead of <code>filter</code>,
<code>map</code>, and <code>reduce</code>.
</SPAN>
<SPAN class=""><BR><SPAN class="stylepoint_body" name="String_Methods__body" id="String_Methods__body" style="display: none"><SPAN class="link_button"><A href="?showone=String_Methods#String_Methods">
<SPAN class=""><BR><SPAN class="stylepoint_body" name="Deprecated_Language_Features__body" id="Deprecated_Language_Features__body" style="display: none"><SPAN class="link_button"><A href="?showone=Deprecated_Language_Features#Deprecated_Language_Features">
link
</A></SPAN>
<P class="">
<SPAN class="stylepoint_section">Definition: </SPAN> String objects include methods for most
functions in the <code>string</code> module.
<SPAN class="stylepoint_section">Definition: </SPAN>
Current versions of Python provide alternative constructs
that people find generally preferable.
</P>
<P class="">
<SPAN class="stylepoint_section">Pros: </SPAN> No need to import the <code>string</code> module;
methods work with both regular byte-strings and Unicode-strings.
</P>
<P class="">
<SPAN class="stylepoint_section">Cons: </SPAN>
None.
</P>
<P class="">
<SPAN class="stylepoint_section">Decision: </SPAN> Use string object methods. The <code>string</code> module is
deprecated in favor of string methods.
<SPAN class=""><PRE class="badcode">No: <span class="external"></span>words = string.split(foo, ':')</PRE></SPAN>
<SPAN class=""><PRE>Yes: <span class="external"></span>words = foo.split(':')</PRE></SPAN>
<SPAN class="stylepoint_section">Decision: </SPAN>
We do not use any Python version which does not support
these features, so there is no reason not to use the new
styles.
<SPAN 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></SPAN>
<SPAN 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>fn(*args, **kwargs)</PRE></SPAN>
</P>
</SPAN></SPAN>
</SPAN>
@ -2011,7 +1983,7 @@ Don'<span class="external"></span>t do this.
<p align="right">
Revision 2.12
Revision 2.14
</p>