REP: 8 Title: Style Guide for Python Code Author: Ken Conley <kwc@willowgarage.com> Status: Active Type: Process Content-Type: text/x-rst Created: 18-Sep-2010 Post-History: 18-Sep-2010
This document gives coding conventions for the Python code comprising the standard library in the main ROS distribution.
Please follow Python's PEP 8 [1] for guidelines on formatting, naming, etc...
roslib is the only ROS Python package you can automatically assume to be importable other than your local files. If your Python package has dependencies, you must include the following header at the top:
import roslib roslib.load_manifest('your_package_name')
roslib.load_manifest looks at your manifest.xml and places your dependencies on your Python path. DO NOT use multiple load_manifest calls. If you need multiple calls, it's probably because you're missing the correct dependencies in your manifest.
All python code must be placed within a module namespace. ROS exports your Python source directory to be on the path of any of your dependencies, so it is important not to accidentally clobber someone else's import. We strongly recommend that this module name be the same as your ROS package name.
There are two recommended code layouts:
Small modules with no msg/srvs:
packagename |- nodes/ |- ROS node executable files |- src/ |- packagename.py |- scripts/ |- non-exported python files
Module with msgs/srvs:
packagename |- nodes/ |- ROS node executable files |- src/ |- packagename/ |- __init__.py |- yourfiles.py |- scripts/ |- non-exported python files
We distinguish between "nodes" and "scripts" for clarity to users. Nodes are executable Python files that conform to the ROS node API. Scripts are executable Python files that do not conform to the ROS node API.
If you don't know what an __init__.py file is, we recommend that you read What is init py used for??
The more complicated layout for msg/srv files is required as the Python msg/srv generators will need to generate files into your package's namespace.
In the rare case that you can't place your source code in src/ (e.g. thirdparty code), you can override the Python export path of your package by editing your manifest.
In ROS, the name of a node type is the same as its executable name. Typically, for python files, this means including #!/usr/bin/env python at the top of your main code file.
If your node is simple, this file may contain the entire code for it. Otherwise, the node file will likely do an import packagename and invoke code there.
NOTE: we strive to keep ROS-specific code separate from reusable, generic code. The separation of 'node files' and files you place in src/packagename helps encourage this.
The current target platform is Python 2.5 [2], though we wish to make code that is easily transitioned to Python 2.6, 2.7, and, more importantly, Python 3000 [3].
This means:
- Use new-style classes
- No
reduce()
.sum()
works in most cases andfor
loops are often as fast or faster - Try to avoid
map()
orfilter()
as they are on Guido's hit list. Use list comprehensions. - Use
raise Exception("msg")
instead ofraise Exception, msg
- No backticks as a shortcut for
repr
- No
<>
, use!=
- Use
from __future__ import division
so that you're using true division, not floor division [4] - Use
subprocess
instead ofpopen2
,os.popen
- Avoid
dict.has_key()
, usekey in dict
instead. - Try to avoid using the results of
zip()
,range()
,map()
, orfilter()
as a list as these will return iterators in the future
All the above are on this list either because:
- They are not compatible with Python 2.5
- They will potentially be eliminated in Python 3000.
Also, be careful not to introduce Python 2.6 features, such as Exception as ex
.
[1] | PEP 8, Style Guide for Python Code, van Rossum http://www.python.org/dev/peps/pep-0008/ |
[2] | REP 3, Target Platforms, Foote, Conley http://www.ros.org/reps/rep-0003.html |
[3] | PEP 3100, Miscellaneous Python 3.0 Plans, Cannon http://www.python.org/dev/peps/pep-3100 |
[4] | PEP 238, Changing the Division Operator, Zadka http://www.python.org/dev/peps/pep-0238 |
This document has been placed in the public domain.