開発環境
- OS: macOS High Sierra - Apple
- Text Editor: Emacs
- プログラミング言語: Python3
- モジュール: sion (GitHub)
load関数の引数がファイル名だと、手元のファイルの読み込みは簡単だけど、データのやり取りでバイナリモードのファイルの読み込みが出来なくて、urllib.responeモジュールのurlopenとかで使えないから変更。
コード(Emacs)
sion.py
# Created by kamimura on 2018/07/21. # Copyright © 2018 kamimura. All rights reserved. import sys import datetime from antlr4 import * from SIONLexer import SIONLexer from SIONParser import SIONParser from SIONVisitor import SIONVisitor def load(file, encoding: str='utf-8', errors: str='strict') -> object: data = file.read() if type(data) == bytes: data = data.decode(encoding, errors) stream = InputStream(data) lexer = SIONLexer(stream) tokens = CommonTokenStream(lexer) parser = SIONParser(tokens) tree = parser.si_self() visitor = SIONVisitor() return visitor.visit(tree) def str_esc(s): for o, n in [('"', '\\"'), ('\n', '\\n'), ('\r', '\\r'), ('\\', '\\\\')]: s = s.replace(o, n) return s def dump(obj, file): t = type(obj) if obj is None: print('nil', file=file, end='') elif t == bool: if obj: print('ture', file=file, end='') else: print('false', file=file, end='') elif t in {int, float}: print(obj, file=file, end='') elif t == str: print(f'"{str_esc(obj)}"', file=file, end='') elif t == bytes: print(f'.Data("{str(obj)[2:-1]}")', file=file, end='') elif t == datetime.datetime: print(f'.Date({t.timestamp(obj)})', file=file, end='') elif t in {list, tuple}: print(f'[', file=file, end='') if len(obj) > 0: for o in obj[:-1]: dump(o, file) print(',', file=file, end='') dump(obj[-1], file) print(']', file=file, end='') elif t == dict: print('[', file=file, end='') ks = list(obj.keys()) if len(ks) == 0: print(':', file=file, end='') elif len(ks) == 1: dump(ks[0], file) print(':', file=file, end='') dump(obj[ks[0]], file) else: for k in ks[:-1]: dump(k, file) print(':', file=file, end='') dump(obj[k], file) print(',', file=file, end='') dump(ks[-1], file) print(':', file=file, end='') dump(obj[ks[-1]], file) print(']', file=file, end='') else: raise TypeError( f"Object of type '{obj.__class__.__name__}' is not SION serializable") if __name__ == '__main__': if len(sys.argv) > 1: filename = sys.argv[1] else: filename = '../test/t.sion' with open(filename) as f: obj = load(f) print(obj) with open('../test/output.sion', 'w') as f: dump(obj, f)
バイナリファイルの読み込みが出来る事を確認。
Python 3
#!/usr/bin/env python3 import pprint from urllib.request import urlopen import sion url = 'https://raw.githubusercontent.com/kamimura/py-sion/master/test/t.sion' with urlopen(url) as res: pprint.pprint(sion.load(res)) with open('sample.sion') as f: pprint.pprint(sion.load(f))
入出力結果(Terminal, Jupyter(IPython))
$ cat sample.sion [ "array" : [ nil, true, 1, // Int in decimal 1.0, // Double in decimal "one", [1], ["one" : 1.0] ], "bool" : true, "data" : .Data("R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"), "date" : .Date(0x0p+0), "dictionary" : [ "array" : [], "bool" : false, "double" : 0x0p+0, "int" : 0, "nil" : nil, "object" : [:], "string" : "" ], "double" : 0x1.518f5c28f5c29p+5, // Double in hexadecimal "int" : -0x2a, // Int in hexadecimal "nil" : nil, "string" : "漢字、カタカナ、ひらがなの入ったstring😇", "url" : "https://github.com/dankogai/", nil : "Unlike JSON and Property Lists,", true : "Yes, SION", 1 : "does accept", 1.0 : "non-String keys.", [] : "like", [:] : "Map of ECMAScript." ]$ ./sample3.py {None: 'Unlike JSON and Property Lists,', True: 'non-String keys.', '[]': 'like', 'array': [None, True, 1, 1.0, 'one', [1], {'one': 1.0}], 'bool': True, 'data': b'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7', 'date': datetime.datetime(1970, 1, 1, 9, 0), 'dictionary': {'array': [], 'bool': False, 'double': 0.0, 'int': 0, 'nil': None, 'object': {}, 'string': ''}, 'double': 42.195, 'int': -42, 'nil': None, 'string': '漢字、カタカナ、ひらがなの入ったstring😇', 'url': 'https://github.com/dankogai/', '{}': 'Map of ECMAScript.'} {None: 'Unlike JSON and Property Lists,', True: 'non-String keys.', '[]': 'like', 'array': [None, True, 1, 1.0, 'one', [1], {'one': 1.0}], 'bool': True, 'data': b'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7', 'date': datetime.datetime(1970, 1, 1, 9, 0), 'dictionary': {'array': [], 'bool': False, 'double': 0.0, 'int': 0, 'nil': None, 'object': {}, 'string': ''}, 'double': 42.195, 'int': -42, 'nil': None, 'string': '漢字、カタカナ、ひらがなの入ったstring😇', 'url': 'https://github.com/dankogai/', '{}': 'Map of ECMAScript.'} $
0 コメント:
コメントを投稿