Naming conventions in pySDC¶
📜 Those rules may not be enforced by the current implementation of pySDC. However, they should be enforced for any contribution.
Naming convention are mostly inspired from the PEP-8 guidelines, even if some of them may be different. Of course, strictly following those rules is not always the best solution, as Guido Von Rossum’s key insight states :
A Foolish Consistency is the Hobgoblin of Little Minds
The most important idea at the end is to find a optimal compromise between
readability : Can someone else easily read and understand my code ?
effectiveness : Does my code avoid kilometers-long lines to do simple things ?
Both aspects are interdependent to ease maintaining/development of any code and improve its attractiveness to potential users.
First definitions¶
Possible Naming formats :
all-lowercase :
variablenamelikethis
snake_case :
variable_name_like_this
PascalCase :
VariableNameLikeThis
camelCase :
variableNameLikeThis
all-uppercase with underscore :
VARIABLE_NAME_LIKE_THIS
all-uppercase with minus :
VARIABLE-NAME-LIKE-THIS
Packages and modules names¶
Modules should have short, all-lowercase names. Underscores can be used in the module name if it improves readability (i.e use snake_case only if it helps, else try to stick to all-lowercase). Python packages should also have short, all-lowercase names, although the use of underscores is discouraged.
Class names¶
Class names should use PascalCase formatting, for instance :
class AdvectionDiffusion(Problem):
pass
The shorter, the better. Also, exception class names should end with the suffix Error
, for instance
class ParameterError(Exception):
pass
Function and variables names¶
Function (or method) and variable names should use camelCase formatting, and same goes for function arguments. For instance :
tLeft = 1
quadType = 'LEGENDRE'
def computeFejerRule(nNodes):
# ...
class NodeGenerator():
def getOrthogPolyCoeffs(self, nCoeffs):
# ...
📜 A few additional notes :
In general, shorter name (eventually with abbreviations) should be favored, as long as it does not deteriorate understandability. For instance
getOrthogPolyCoeffs
rather thangetOrthogonalPolynomialCoefficients
.Suffix
s
for plural should be used even with abbreviations for consistency (e.gnCoeffs
,nNodes
, …).Acronyms can be used to simplify variable names, but try not to start with it. For instance, favor
jacobiMSSDC
ormultiStepSDCJacobi
rather thanMSSDCJacobi
. In general, acronyms should be put at the end of variable names.Underscore can exceptionally be used at the end of variable names when it make readability better and ease further developments. In that case, the characters after the underscore should be all-uppercase with underscore (minus is not allowed by Python syntax). For instance when defining the same method with different specializations :
class MySweeper(Sweeper):
def __init__(self, initSweep):
try:
self.initSweep = getattr(self, f'_initSweep_{initSweep}')
except AttributeError:
raise NotImplementedError(f'initSweep={initSweep}')
def _initSweep_COPY(self):
pass
def _initSweep_SPREAD(self):
pass
# ... other implementations for initSweep
Private and public attributes¶
There is no such thing as private or public attributes in Python. But some attributes, if uses only within the object methods, can be indicated as private using the _
prefix. For instance :
class ChuckNorris():
def __init__(self, param):
self.param = param
def _think(self):
print('...')
def act(self):
if self.param == 'doubt':
self._think()
print('*?%&$?*§"$*$*§#{*')
📜 In general, variable name starting with double underscore __
are usually left for Python built-in names, e.g __dict__
, __init__
, …
Constants¶
Constants are usually defined on a module level and written in all-uppercase with underscores (all-uppercase with minus are not allowed by Python syntax). Examples :
NODE_TYPES = ['EQUID', 'LEGENDRE', 'CHEBY-1', 'CHEBY-2', 'CHEBY-3', 'CHEBY-4']
QUAD_TYPES = ['GAUSS', 'RADAU-LEFT', 'RADAU-RIGHT', 'LOBATTO']
For constant string values, however, favor the use of all uppercase with minus, e.g RADAU-RIGHT
, LEGENDRE-NUMPY
to distinguish those from constants names.
🔔 When constants are used, for instance, to select method specializations (with suffix using all-uppercase with underscore), it is probably better to keep all-uppercase with minus for constant string values and add a character replacement in between, for instance :
class MySweeper(Sweeper):
def __init__(self, initSweep):
try:
self.initSweep = getattr(self, f'_initSweep_{initSweep.replace('-','_')}')
except AttributeError:
raise NotImplementedError(f'initSweep={initSweep}')
def _initSweep_COPY_PASTE(self):
pass
def _initSweep_SPREAD_OUT(self):
pass
# ... other implementations for initSweep
⬅️ Back to Continuous Integration — ⬆️ Contributing Summary — ➡️ Next to Custom Implementations