| 97 | === configuration === |
| 98 | |
| 99 | ==== minimizing configuration ==== |
| 100 | |
| 101 | * Do not implement configuration files for modules or libraries -- code that is going to be used by other code. Only applications -- code that is going to be used by humans -- have configuration files. Modules and libraries get "configured" by the code that calls them, for example by passing arguments to their constructors. |
| 102 | * If there are constant values which end-users do not need to modify, then do not make them configurable, but put them in all-caps variables at the beginning of the Python file in which they are used. |
| 103 | * Design algorithms so that they have as few "voodoo constants" and "tweakable parameters" as possible. |
| 104 | |
| 105 | ==== how to implement configuration ==== |
| 106 | |
| 107 | Whether in application code or in library code, never pass configuration values via a configuration object. Instead use Python parameters. For example -- here's another real-life example -- do not write |
| 108 | |
| 109 | {{{ |
| 110 | class BlockStore: |
| 111 | def __init__(self, confdict={}, recoverdb=True, name='*unnamed*'): |
| 112 | if confdict.has_key('MAX_MEGABYTES'): |
| 113 | self.maxspace = (2**20) * int(confdict.get('MAX_MEGABYTES')) |
| 114 | else: |
| 115 | self.maxspace = None |
| 116 | self.basepath = os.path.abspath(confdict.get("PATH", "")) |
| 117 | self.maintainertype = confdict.get("MAINTAINER", "rnd").lower() |
| 118 | self.backendtype = confdict.get("BACKEND", "flat").lower() |
| 119 | }}} |
| 120 | |
| 121 | , but instead write |
| 122 | |
| 123 | {{{ |
| 124 | class BlockStore: |
| 125 | def __init__(self, maxspace=None, path="", maintainertype="rnd", backendtype="flat", recoverdb=True, name='*unnamed*'): |
| 126 | self.basepath = os.path.abspath(path) |
| 127 | self.maintainertype = maintainertype |
| 128 | self.backendtype = backendtype |
| 129 | }}} |
| 130 | . |
| 131 | |
| 132 | |
146 | | === configuration === |
147 | | |
148 | | ==== minimizing configuration ==== |
149 | | |
150 | | * Do not implement configuration files for modules or libraries -- code that is going to be used by other code. Only applications -- code that is going to be used by humans -- have configuration files. Modules and libraries get "configured" by the code that calls them, for example by passing arguments to their constructors. |
151 | | * If there are constant values which end-users do not need to modify, then do not make them configurable, but put them in all-caps variables at the beginning of the Python file in which they are used. |
152 | | * Design algorithms so that they have as few "voodoo constants" and "tweakable parameters" as possible. |
153 | | |
154 | | ==== how to implement configuration ==== |
155 | | |
156 | | Whether in application code or in library code, never pass configuration values via a configuration object. Instead use Python parameters. For example -- here's another real-life example -- do not write |
157 | | |
158 | | {{{ |
159 | | class BlockStore: |
160 | | def __init__(self, confdict={}, recoverdb=True, name='*unnamed*'): |
161 | | if confdict.has_key('MAX_MEGABYTES'): |
162 | | self.maxspace = (2**20) * int(confdict.get('MAX_MEGABYTES')) |
163 | | else: |
164 | | self.maxspace = None |
165 | | self.basepath = os.path.abspath(confdict.get("PATH", "")) |
166 | | self.maintainertype = confdict.get("MAINTAINER", "rnd").lower() |
167 | | self.backendtype = confdict.get("BACKEND", "flat").lower() |
168 | | }}} |
169 | | |
170 | | , but instead write |
171 | | |
172 | | {{{ |
173 | | class BlockStore: |
174 | | def __init__(self, maxspace=None, path="", maintainertype="rnd", backendtype="flat", recoverdb=True, name='*unnamed*'): |
175 | | self.basepath = os.path.abspath(path) |
176 | | self.maintainertype = maintainertype |
177 | | self.backendtype = backendtype |
178 | | }}} |
179 | | . |
180 | | |
181 | | |