| | 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 | | |