blob: 3f4c1df6a6f8c3606267f13362226c2672159865 [file] [log] [blame]
=========================
Python Coding Conventions
=========================
currently under development, your input appreciated
--------------------------
Indentation and formatting
--------------------------
* 4 spaces of indentation
* do not use tabs for source code formatting
* tabs are okay within strings, but using \t is preferred
-----------------
Coding Principles
-----------------
* Class __init__ methods should return completed valid objects with all
fields initialized to a valid state. If more fields are later added to the
object it is better for the constructor to fail due to insufficient
parameters than for code to "work" until later code makes reference to a
not-completely-initialized object.
This is bad:
o = gpObject() # object still uninitialized
o.setObjectName('hello')
o.setObjectValue('world')
This is better:
o = gpObject(name='hello', value='world')
* default values for parameters should be used responsibly.
(this needs to be better defined)
Never set a default value for the fundamental aspects of a class.
This is bad:
class GpDB():
def __init__(self, dbid=-1, ...):
self.dbid = dbid # ^^ Setting the core aspects of the class
* Where possible functions should have relatively few parameters. While it
is not always possible to keep the number of parameters low it leads to
clearer code.
* If a function has more 5 or more parameters it is better to call that
function with parameters set by name for clarity.
This is unclear:
db = GpDB(-1, 'p', 0, 'm', 's', 'u', 'localhost', 'localhost', 5432,
datadir, None)
This is better:
db = GpDB(content = -1, preferred_role = 'p', dbid = 0, role = 'p',
mode = 's', status = 'u', hostname = 'localhost',
address = 'localhost', port = 5432, datadir = '/gpdata/gp-1',
replicationPort = None)
* Avoid masking functions in the builtin namespace:
This is bad:
def foo(name):
str = "test" # masks the builtin str() function
x = str(name) # this is an error due to the above
This is better:
def foo(name):
test_string = "test"
...
* Generic code should be placed in a generic location.
If you have a generic class that turns an xml file into a generic python
xml object, don't place it in a file called gpcheckosXml.py.
* Exceptions
(need to develop some convention guidance)
----------
Commenting
----------
* Extensive commenting of code is encouraged.
* Comments should be informative and add value
This is bad:
x = 5 # Set the value to five
This is better:
x = 5 # The index of "hostname" in the above select statement
* When comment a function it is better to use comments that can be recognised
by pydoc than ones that can are not recognised. This means using strings
for commenting rather than "#".
This is bad:
def foo():
# Function description, not recognized by pydoc
This is good:
def foo():
"Function desciption"
or
def foo()
"""
Longer description
With multiple lines
"""
------------------
Naming Conventions
------------------
* Within the gppylib module class names should begin with the prefix Gp and
use camel-case rather than underscores:
class GpExampleClass():
* Function names should begin with a lowercase letter and use camel-case
rather than underscores:
def doSomethingAmazing():
* Function parameters should begin with a lowercase letter and use camel-case
rather than underscores:
def doSomethingAmazing(usingSomeParameter):
* Class member variables should be private (named prefixed with __).
By keeping class variables private and exposing them via accessor function
it allows the classes to be more easily modified in the future.
class GpExampleClass:
def __init__(self, name):
self.__name = name
def getExampleName(self):
return self.__name
* Class member functions should be descriptive of the class.
Since python is an interpreted dynamically typed language it can be
difficult to keep track of what calls what, having easily distinguished
function names makes it easier to track call graphs so that modifications
can be done more easily.
This is bad, the function name is too generic which makes identifying
callers more difficult.
class GpExampleClass:
def getData():
...
This is better, the function name is more distinct.
class GpExampleClass:
def getExampleData():
...
* Global variables should be named with a leading "g" prefix:
gMyGlobalData = None
* Global constant values should be all-caps separated by _:
MY_GLOBAL_CONSTANT = 5