Use python as the configuration file

Source: Internet
Author: User

There is no doubt that you need a configuration file. It is said that the configuration file can make your system customizable. There are three major trends in customizing the system, which determine the format of the three configuration files: 1. graphical interface configuration tool. After the popularity of computers and Windows, our users are no longer hackers. Maybe your users will never open your configuration file. You need to give him a graphical tool and change his diapers. When humans never read the configuration file, the simpler way to make the system is to store the configuration in a format that is the easiest to understand on the machine. Generally, this is a binary file. Pickle is a typical option in Python. After a few decades, some people began to think that using the format that both machines and people can understand (or cannot understand) is a good idea, so that XML is available. Here, I just want to tell you that XML is really a good thing, but in most cases you don't really need it. In Zope/Plone, configurations are stored in the ZODB database on a large scale. In this way, the first configuration file type is generated, which is unreadable by humans. 2. configuration files in common format, including the famous httpd. conf and INI. Basically, INI is weak, and the INI support library does not provide functions such as value verification or even setting the default value of variables. Therefore, unless the project is very small, you should not use the INI format. The INI format is not used at any time, which helps you develop good habits. The configuration file of httpd. conf Like is the peak of the configuration file format. In Python, ZConfig (located in Zope2/Zope3) provides support for this format. I have an introduction here: http://eishn.blog.163.com/blog/static/65231820069310828642/ it is just an introduction, you need to read the documentation, source code or examples to fully understand how ZConfig works. Although it is not easy, understanding ZConfig will help you quickly master the design philosophy of the configuration file. Conventional configuration file design and parsing are too complex, so you can only understand. 3. Use Python as the configuration file. Why not? At present, many C Programs are using Python as the configuration file, and the Lighttpd configuration file is no more than ten. Here is an example: # demo_conf.py # configuration file host = '2017. 0.0.1 'port = 8080 # demo. py import demo_conf print demo_conf.host, demo_conf.port uses the Python script as the configuration file, which is simple in program implementation and requires no format conversion, and has powerful functions. This scheme has begun to declare war on the traditional configuration file format. Finally, I modified the original plan to introduce ZConfig. Today I will introduce this scheme again. Next, let's design our own configuration file format. To figure out how to design a configuration file, we first need to figure out which data types in the system need to be configured, and to what extent they can be configured. Based on experience, three types of data can be customized in a system: 1. "static" data, which is defined by # define in C language. Such data is dynamic only during the development period. Once the system completes development, such data is static. This type of data has the lowest change frequency. Python programmers usually write the variable name up and put it in "config. py" and import it using import config. 2. "default" configuration, which is the biggest source of chaos in the project configuration. The default configuration is the data that users can modify in the configuration file. They are not mandatory and have default values. You will soon find that many "default" configurations will never be modified by users. In this case, these default configurations are actually "static" data, you should write "config. py ". Others are common configurations with default values. The data should be written to the "etc" configuration file. Obviously, a variable cannot exist in both config. py and etc configuration files. The problem is that it is difficult and uncertain to determine whether a variable belongs to "static" data or "default" configuration. This eventually led to the changing definition of your configuration file, and your project was in a storm. 3. configuration items should be placed in the configuration file without any doubt. After the system is put into use, this is the data type with the highest change frequency. Another major challenge in the configuration file is variable type verification. Variable type verification is annoying because you need to determine whether a configuration variable exists, whether the type matches, or whether it is out of bounds, and whether it is given the default value. The worst thing is that you still need to answer the question: do you need to write the default value in the configuration file. To solve all these problems, Schema was invented. Unlike traditional configuration files, using Python as a configuration file makes Schema compilation quite flexible. In addition, the Schema helps you make the configuration file in the Python format more readable. The following shows how to write a Schema when Python is used as the configuration file format. #/PATH/TO/ETC/demo_conf.py # Configuration File import schemaServer (host = '2017. 0.0.1 ', port = 8080) #-EOF-#/PATH/TO/ETC/schema. py # config = {} def Server (** args): config ['host'] = args. get ('host', '0. 0.0.0 ') # The default value is try: config ['Port'] = int (args. get ('Port', 8080) # Carry verification token t ValueError: raise ValueError, 'you must be an integer '#-EOF-#/PATH/TO/BIN/demo. py # import syssys. path. append (r '/PATH/TO/ETC') import schema, demo_confprint sche Ma. config ['host'], schema. config ['Port'] #-EOF-Okay. Next we need to make demo_conf.py more like a configuration file, because "import schema" is not something that should be in a configuration file, we want to make "Server" a pre-imported variable. Finally, we need to change demo_conf.py to demo. conf. In this way, we will be able to access custom import technology again after PyQt4 is a breeze. This time we will use a similar technique, which is also an import hook. The difference is that this time we will not hook the hook to the Python interpreter. ######################################## ###########################-BOF-# pyetc. py # Python-format configuration file support library # import sys, OS. pathModule = type (sys) # technical replay modules ={} # cache the imported etc (configuration) module # import any file conforming to the Python syntax # usage: # module = pyetc. load (the complete file path contains the extension, the preload variable, and the custom return module type) # def load (fullpath, env ={}, Module = module): try: code = open (fullpath ). read () handle T IOError: raise ImportError, 'no module named % s' % fullpathf Ilename = OS. path. basename (fullpath) try: return modules [filename] cipher t KeyError: passm = module (filename) m. _ module_class _ = modulem. _ file _ = fullpathm. _ dict __. update (env) exec compile (code, filename, 'exec ') in m. _ dict _ modules [filename] = mreturn m # Remove imported modules # usage: # module = unload (module) # def unload (m): filename = OS. path. basename (m. _ file _) del modules [filename] return None # re-import module # usage: # modul E = pyetc. reload (module) # def reload (m): fullpath = m. _ file _ try: code = open (fullpath ). read () handle T IOError: raise ImportError, 'no module named % s' % fullpathenv = m. _ dict _ module_class = m. _ module_class _ filename = OS. path. basename (fullpath) m = module_class (filename) m. _ file _ = fullpathm. _ dict __. update (env) m. _ module_class _ = module_classexec compile (code, filename, 'exec ') in m. _ dict _ module S [filename] = mreturn m ################################# ##################################-EOF-let's try it. #/PATH/TO/ETC/demo. conf # configuration file host = '2017. 0.0.1 'port = 8080 #-EOF-# demo. pyimport pyetcconf = pyetc. load (R'/PATH/TO/ETC/demo. conf ') print conf. host, conf. port #-EOF-Finally, a complete example: #/PATH/TO/ETC/demo. conf # Server option # Server (port = 8080 # Listen to port 8080) # process controller option # Daemon (# Use Socket to publish a process controller # address = ('0. 0.0.0 ', 10080), # use the File publishing process controller address = var ('demo. pid '), # server process program = bin ('server. py '), # debug switch verbose = True) #-EOF-#/PATH/TO/BIN/schema. py # path tool import sys, OS. pathDEMO_HOME = R'/PATH/TO/demo' ETC = lambda filename: OS. path. join (DEMO_HOME, 'etc ', filename) VAR = lambda filename: OS. path. join (DEMO_HOME, 'var', filename) BIN = lambda filename: OS. path. join (DEMO_HOME, 'bin', filename) # class Config (dict): # You can access the dictionary Key like an attribute # dict. key is equivalent to dict [key] def _ getattr _ (self, name): return self [name] # configure the default config = Config ({'server ': config ({'Port': 8080 # server uses port 8080}), 'daemon': Config ({'address': VAR ('daemon. pid '), # pid file 'signature': BIN ('server. py '), # Server program 'verbo': True}) # configuration interface (without verification) def server (** args): config ['server']. update (args) def Daemon (** args): config ['daemon']. update (args) # configuration file "demo. conf "visible variable env = {'server': Server, 'daemon': Daemon, 'etc ': etc, 'var': var, 'bin ': BIN} #-EOF-#/PATH/TO/BIN/demo. py # Start a Daemon manager here, # Note: The daemon here. py is a hypothetical library, so you don't need to worry about import pyetcfrom daemon import Daemondef start (): # Read the configuration file # demo. confpyetc. load (schema. ETC ('demo. conf '), env = schema. env) conf = schema. config. daemon # create a Daemon object daemon = Daemon (address = conf. address, # process controller address/pid file location program = conf. program, # The background process program location verbose = conf. verbose # Debug) print 'process manager has started 'daemon () if _ name _ = '_ main _': start () #-EOF-
from: http://eishn.blog.163.com/blog/static/6523182007236721876/

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.