##language:zh ::-- limodou [<>] <> = Obj2Ini = ''类Ini形式的对象序列化模块'' == 说明 == 参见:[[http://www.donews.net/limodou/archive/2005/04/09/328275.aspx|类ini形式的对象序列化模块]] == 代码 == {{{ #!python #coding=utf-8 # dump python object to ini format file # Author: limodou (chatme@263.net) # Copyleft GPL # $Id: obj2ini.py,v 1.2 2005/04/21 15:42:39 limodou Exp $ # # 2005/07/31 # 1. 增加变量的支持。 # 2. 修改输出的ini格式为第一行为#obj表示是对象,#var表示是变量。 # 同时为了兼容性,当第一行不是#var或#obj时默认为#obj。 # 3. 修改load方法的调用参数 import types import sys import locale import types def dump(obj, filename, encoding=None): encoding = __getdefaultencoding(encoding) if hasattr(filename, "write"): f = filename else: f = file(filename, "w") if isinstance(obj, types.InstanceType): objects = {} f.write("#obj\n") f.write("[=%s.%s]\n" % (obj.__class__.__module__, obj.__class__.__name__)) for key, value in vars(obj).items(): if isinstance(value, types.InstanceType): objects[key] = value else: __write_var(f, key, value, encoding) for key, value in objects.items(): __dumpsubobj(value, key, '', f, encoding) else: f.write("#var\n") f.write(__uni_prt(obj, encoding)) class EmptyClass: pass def __getparentobjname(name): a = name.split('.') return '.'.join(a[:-1]) def __getmoduleandclass(name): a = name.split('.') return '.'.join(a[:-1]), a[-1] def load(filename, obj=None, encoding=None): encoding = __getdefaultencoding(encoding) if hasattr(filename, "read"): f = filename else: f = file(filename, "r") firstline = f.readline() if firstline.startswith('#obj') or not firstline.startswith('#var'): if not firstline.startswith('#obj'): f.seek(0) objects = {} namespace = {} if not obj: obj = EmptyClass() currentobj = obj parentobj = obj for line in f: line = line.strip() if not line: continue if line[0] in ('#', ';'): continue if line.startswith('[') and line.endswith(']'): #sub object #set original class classname, classinfo = line[1:-1].split('=') module, _class = __getmoduleandclass(classinfo) __import__(module) mod = sys.modules[module] _klass = getattr(mod, _class) if classname: sub = EmptyClass() parentname = __getparentobjname(classname) setattr(parentobj, classname, sub) else: sub = currentobj parentname = '' sub.__class__ = _klass if parentname: parentobj = objects[parentname] else: parentobj = currentobj objects[classname] = sub currentobj = sub else: if line.find('='): delimeter = '=' else: delimeter = ':' key, value = line.split(delimeter, 1) key = key.strip() exec __filter(line, encoding) in namespace setattr(currentobj, key, namespace[key]) return obj else: line = f.readline() namespace = {} exec __filter('var='+line, encoding) in namespace return namespace['var'] def __dumpsubobj(obj, objname, parentname, filename, encoding=None): if hasattr(filename, "write"): f = filename else: f = file(filename, "w") if parentname: f.write("\n[%s.%s=%s.%s]\n" % (parentname, objname, obj.__class__.__module__, obj.__class__.__name__)) else: f.write("\n[%s=%s.%s]\n" % (objname, obj.__class__.__module__, obj.__class__.__name__)) objects = {} for key, value in vars(obj).items(): if isinstance(value, types.InstanceType): objects[key] = value else: __write_var(f, key, value, encoding) for key, value in objects.items(): __dumpsubobj(value, key, objname, f, encoding) def __write_var(f, key, var, encoding): f.write("%s=%s\n" % (key, __uni_prt(var, encoding))) def __getdefaultencoding(encoding): if not encoding: encoding = locale.getdefaultlocale()[1] if not encoding: encoding = sys.getfilesystemencoding() return encoding def __uni_prt(a, encoding=None): escapechars = [("\\", "\\\\"), ("'", r"\'"), ('\"', r'\"'), ('\b', r'\b'), ('\t', r"\t"), ('\r', r"\r"), ('\n', r"\n")] s = [] encoding = __getdefaultencoding(encoding) if isinstance(a, (list, tuple)): if isinstance(a, list): s.append('[') else: s.append('(') for i, k in enumerate(a): s.append(__uni_prt(k, encoding)) if i