Python: Best practice for including a version number in an app?
I have a PyQt application that reads and writes data files. I am including a 'version number' in each file written. This is a simple number similar to: 1.2 or something (major and minor versions).
I am doing this so that I can change the format of these data files in future versions and then still correctly parse them simply by checking to see what the version is inside the file.
My question is what is the best practice for keeping this number stored inside the app itself. I.e. do I 开发者_开发百科just hard-code the app version number into the class that is responsible for reading and writing files? Or should I have some sort of object/variable stored at the top-level of the app and somehow access it from the class responsible for reading and writing these files. If the latter, how do I store it and how do I access it?
Thanks.
First, version the data format separately from the app, if not already doing so. Second, have separate classes for newer versions of the format. If the format is completely backwards compatible, you can drop the classes for older versions. As for the file structure, you could have something like:
- DF
- __init__.py
- dfbase.py
- v1_1
- __init__.py
- format.py
- v2_0
- __init__.py
- format.py
where "df" stands for the data format name. The package initialization files import the appropriate packages and define a structure or function to make them accessible. The top-level __init__.py should also define a factory function to create data format objects, so you don't have to.
DF/__init__.py:
from df.dfbase import DFBase
from v1_1 import DF as DF1
from v2_0 import DF as DF2
versions = {
'1.0': DF1, # let's say minor versions are fully backwards compatible
'1.1': DF1,
'2.0': DF2
}
def create(file):
"""Factory function. Loads data from 'file', returns a DF of the appropriate
version.
"""
...
DF/v1_1/__init__.py:
__version__ = '1.1'
# previous versions that this one is backwards compatible with
previous = ['1.0']
from format import DF
DF/v1_1/format.py:
from df import DFBase
class DF(DFBase):
...
DF/v2_0/__init__.py:
__version__ = '2.0'
from format import DF
With a little more coding in DF/__init__.py, you could automate the import and registration of format versions.
import glob, sys
from ndf.ndfbase import NDFBase
formats={}
for ver in glob.iglob('v*_*'):
pkg = '{0}.{1}'.format(__package__, ver)
__import__(pkg)
formats[sys.modules[pkg].__version__] = sys.modules[pkg]
if hasattr(sys.modules[pkg], 'previous'):
for prev in sys.modules[pkg].previous:
formats[prev] = sys.modules[pkg]
def create(file):
"""Factory function. Loads data from 'file', returns a DF of the appropriate
version.
"""
...
Many open source projects (e.g. numpy, fabric) have a module called "version", which contains version information in top-level variables. See e.g. fabric's version file.
Personally, I wouldn't do it manually this way. I'd save my code in Subversion and let it maintain the revision numbers for me.
精彩评论