Differences between revisions 1 and 5 (spanning 4 versions)
Revision 1 as of 2005-04-08 16:31:56
Size: 5896
Editor: limodou
Comment:
Revision 5 as of 2009-12-25 07:08:56
Size: 7570
Editor: localhost
Comment: converted to 1.6 markup
Deletions are marked like this. Additions are marked like this.
Line 3: Line 3:
::-- limodou [[[DateTime(2005-04-08T16:31:56Z)]]]
[[TableOfContents]]
::-- limodou [<<DateTime(2005-04-08T16:31:56Z)>>]
<<TableOfContents>>
Line 8: Line 8:
参见:[http://www.donews.net/limodou/archive/2005/04/09/328275.aspx 类ini形式的对象序列化模块] 参见:[[http://www.donews.net/limodou/archive/2005/04/09/328275.aspx|类ini形式的对象序列化模块]]
Line 17: Line 17:
# $Id$ # $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方法的调用参数
Line 22: Line 28:
import types
Line 24: Line 31:
    encoding = __getdefaultencoding(encoding)
Line 29: Line 38:
    objects = {}
    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)    
    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))
Line 50: Line 64:
def load(obj, filename, encoding=None): def load(filename, obj=None, encoding=None):
    encoding = __getdefaultencoding(encoding)
Line 56: Line 72:
    objects = {}
    namespace = {}
    currentobj = 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)
    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
Line 75: Line 108:
                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])
                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']
Line 115: Line 144:
     def __getdefaultencoding(encoding):
    if not encoding:
        encoding = locale.getdefaultlocale()[1]
    if not encoding:
        encoding = sys.getfilesystemencoding()
    return encoding
Line 117: Line 153:
    escapechars = [("\\", "\\\\"), ("'", r"\'"), ('\"', r'\"'), ('\b', r'\b'),
        ('\t', r"\t"), ('\r', r"\r"), ('\n', r"\n")]
Line 118: Line 156:
    if not encoding:
        encodeing = locale.getdefaultlocale()[1]
    if not encoding:
        encoding = sys.getfilesystemencoding()
    encoding = __getdefaultencoding(encoding)
Line 144: Line 179:
        t = a.replace("\\", "\\\\")
t = t.replace("'", r"\'")
        t = a
        fo
r i in escapechars:
    t = t.replace(i[0], i[1])
Line 148: Line 184:
        t = a.replace("\\", "\\\\")
t = t.replace("'", r"\'")
        t = a
        fo
r i in escapechars:
    t = t.replace(i[0], i[1])
Line 180: Line 217:
            self.c = unicode("中'国", 'utf-8')             self.c = unicode("中\\'国", 'utf-8')
Line 187: Line 224:
    f = "obj2ini.ini"     f = "test1.ini"
Line 189: Line 226:
    b.s = "aa\ba\"a\ns'ss\tsdd\r"
Line 194: Line 232:
    s = A()
    
load(s, f)
    s = load(f)
Line 197: Line 234:
         f = sys.stdout
    dump(s, f)
    print s.__class__.__name__
    
# f = sys.stdout
# dump(s, f)

    a = ['a', 'b',(1,2), '中文', {'a':[1,2,3]}]
    dump(a, 'test2.ini')
    b = load('test2.ini')
    print b

::-- limodou [2005-04-08 16:31:56]

Obj2Ini

类Ini形式的对象序列化模块

说明

参见:类ini形式的对象序列化模块

代码

   1 #coding=utf-8
   2 # dump python object to ini format file
   3 # Author: limodou ([email protected])
   4 # Copyleft GPL
   5 # $Id: obj2ini.py,v 1.2 2005/04/21 15:42:39 limodou Exp $
   6 #
   7 # 2005/07/31 
   8 #            1. 增加变量的支持。
   9 #            2. 修改输出的ini格式为第一行为#obj表示是对象,#var表示是变量。
  10 #            同时为了兼容性,当第一行不是#var或#obj时默认为#obj。
  11 #            3. 修改load方法的调用参数
  12 
  13 import types
  14 import sys
  15 import locale
  16 import types
  17 
  18 def dump(obj, filename, encoding=None):
  19     encoding = __getdefaultencoding(encoding)
  20 
  21     if hasattr(filename, "write"):
  22         f = filename
  23     else:
  24         f = file(filename, "w")
  25     
  26     if isinstance(obj, types.InstanceType):
  27         objects = {}
  28         f.write("#obj\n")
  29         f.write("[=%s.%s]\n" % (obj.__class__.__module__, obj.__class__.__name__))
  30         for key, value in vars(obj).items():
  31             if isinstance(value, types.InstanceType):
  32                 objects[key] = value
  33             else:
  34                 __write_var(f, key, value, encoding) 
  35         for key, value in objects.items():
  36             __dumpsubobj(value, key, '', f, encoding)
  37     else:
  38         f.write("#var\n")
  39         f.write(__uni_prt(obj, encoding))
  40     
  41 class EmptyClass:
  42     pass
  43 
  44 def __getparentobjname(name):
  45     a = name.split('.')
  46     return '.'.join(a[:-1])
  47 
  48 def __getmoduleandclass(name):
  49     a = name.split('.')
  50     return '.'.join(a[:-1]), a[-1]
  51 
  52 def load(filename, obj=None, encoding=None):
  53     encoding = __getdefaultencoding(encoding)
  54 
  55     if hasattr(filename, "read"):
  56         f = filename
  57     else:
  58         f = file(filename, "r")
  59 
  60     firstline = f.readline()
  61     if firstline.startswith('#obj') or not firstline.startswith('#var'):
  62         if not firstline.startswith('#obj'):
  63             f.seek(0)
  64         objects = {}
  65         namespace = {}
  66         if not obj:
  67             obj = EmptyClass()
  68         currentobj = obj
  69         parentobj = obj
  70         for line in f:
  71             line = line.strip()
  72             if not line: continue
  73             if line[0] in ('#', ';'): continue
  74             if line.startswith('[') and line.endswith(']'): #sub object
  75                 #set original class 
  76                 classname, classinfo = line[1:-1].split('=')
  77                 module, _class = __getmoduleandclass(classinfo)
  78                 __import__(module)
  79                 mod = sys.modules[module]
  80                 _klass = getattr(mod, _class)
  81                 if classname:
  82                     sub = EmptyClass()
  83                     parentname = __getparentobjname(classname)
  84                     setattr(parentobj, classname, sub)
  85                 else:
  86                     sub = currentobj
  87                     parentname = ''
  88                 sub.__class__ = _klass
  89                 if parentname:
  90                     parentobj = objects[parentname]
  91                 else:
  92                     parentobj = currentobj
  93                 objects[classname] = sub
  94                 currentobj = sub
  95             else:
  96                 if line.find('='):
  97                     delimeter = '='
  98                 else:
  99                     delimeter = ':'
 100                 key, value = line.split(delimeter, 1)
 101                 key = key.strip()
 102                 exec __filter(line, encoding) in namespace
 103                 setattr(currentobj, key, namespace[key])
 104         return obj
 105     else:
 106         line = f.readline()
 107         namespace = {}
 108         exec __filter('var='+line, encoding) in namespace
 109         return namespace['var']
 110 
 111 def __dumpsubobj(obj, objname, parentname, filename, encoding=None):
 112     if hasattr(filename, "write"):
 113         f = filename
 114     else:
 115         f = file(filename, "w")
 116     
 117     if parentname:
 118         f.write("\n[%s.%s=%s.%s]\n" % (parentname, objname, obj.__class__.__module__, obj.__class__.__name__))
 119     else:
 120         f.write("\n[%s=%s.%s]\n" % (objname, obj.__class__.__module__, obj.__class__.__name__))
 121     objects = {}
 122     for key, value in vars(obj).items():
 123         if isinstance(value, types.InstanceType):
 124             objects[key] = value
 125         else:
 126             __write_var(f, key, value, encoding) 
 127     for key, value in objects.items():
 128         __dumpsubobj(value, key, objname, f, encoding)    
 129         
 130 def __write_var(f, key, var, encoding):
 131     f.write("%s=%s\n" % (key, __uni_prt(var, encoding)))
 132     
 133 def __getdefaultencoding(encoding):
 134     if not encoding:
 135         encoding = locale.getdefaultlocale()[1]
 136     if not encoding:
 137         encoding = sys.getfilesystemencoding()
 138     return encoding
 139         
 140 def __uni_prt(a, encoding=None):
 141     escapechars = [("\\", "\\\\"), ("'", r"\'"), ('\"', r'\"'), ('\b', r'\b'), 
 142         ('\t', r"\t"), ('\r', r"\r"), ('\n', r"\n")]
 143     s = []
 144     encoding = __getdefaultencoding(encoding)
 145     if isinstance(a, (list, tuple)):
 146         if isinstance(a, list):
 147             s.append('[')
 148         else:
 149             s.append('(')
 150         for i, k in enumerate(a):
 151             s.append(__uni_prt(k, encoding))
 152             if i<len(a)-1:
 153                 s.append(', ')
 154         if isinstance(a, list):
 155             s.append(']')
 156         else:
 157             s.append(')')
 158     elif isinstance(a, dict):
 159         s.append('{')
 160         for i, k in enumerate(a.items()):
 161             key, value = k
 162             s.append('%s: %s' % (__uni_prt(key, encoding), __uni_prt(value, encoding)))
 163             if i<len(a.items())-1:
 164                 s.append(', ')
 165         s.append('}')
 166     elif isinstance(a, str):
 167         t = a
 168         for i in escapechars:
 169             t = t.replace(i[0], i[1])
 170         s.append("'%s'" % t)
 171     elif isinstance(a, unicode):
 172         t = a
 173         for i in escapechars:
 174             t = t.replace(i[0], i[1])
 175         s.append("u'%s'" % t.encode(encoding))
 176     else:
 177         s.append(str(a))
 178     return ''.join(s)
 179 
 180 def __filter(s, encoding):
 181     import StringIO
 182     import tokenize
 183     import token
 184     
 185     f = StringIO.StringIO(s)
 186     g = tokenize.generate_tokens(f.readline)
 187     slist = []
 188     namespace = {}
 189     for tokentype, t, start, end, line in g:
 190         if tokentype == token.STRING:
 191             if t[0] == 'u':
 192                 exec "v=" + t[1:] in namespace
 193                 slist.append(repr(unicode(namespace["v"], encoding)))
 194             else:
 195                 slist.append(t)
 196         else:
 197             slist.append(t)
 198     return ''.join(slist)
 199                 
 200 if __name__ == '__main__':
 201     class A:
 202         a = 1
 203         def __init__(self):
 204             self.b = 1
 205             self.c = unicode("\\'", 'utf-8')
 206             self.d = (self.c, self.b)
 207             self.e = [self.b, self.c, self.d]
 208             self.f = {self.b:self.c, self.d:self.e}
 209     
 210     a = A()
 211     #f = sys.stdout
 212     f = "test1.ini"
 213     b = A()
 214     b.s = "aa\ba\"a\ns'ss\tsdd\r"
 215     c = A()
 216     a.obj = b
 217     a.obj.obj = c
 218     dump(a, f)
 219     
 220     s = load(f)
 221     print vars(s)
 222     print s.__class__.__name__
 223     
 224 #    f = sys.stdout
 225 #    dump(s, f)
 226 
 227     a = ['a', 'b',(1,2), '中文', {'a':[1,2,3]}]
 228     dump(a, 'test2.ini')
 229     b = load('test2.ini')
 230     print b

Obj2Ini (last edited 2009-12-25 07:08:56 by localhost)