파이썬 코드 읽어보기 - json/tool.py

json - JSON encoder and decoder

파이썬 코드 읽어보기 첫 번째 시리즈는 json입니다.

import json

개발 중 흔하게 만나던 json의 내부는 어떻게 되어 있는지 같이 확인해봅시다.

저는 cpython repository에서 코드를 확인해봤습니다. 파이썬 코드는 ./Lib/ 디렉토리 아래에서 확인할 수 있습니다.

cpython/Lib/json/ 디렉토리안의 내용입니다.

  • __init__.py
  • decoder.py
  • encoder.py
  • scanner.py
  • tool.py

본 글에서는 tool.py를 확인해보겠습니다.

tool.py

메소드 및 주요 변수 중심으로 천천히 설명하겠습니다. 50여줄의 간단한 코드이지만, 커맨드라인을 통해 파이썬 모듈을 실행할 수 있도록 하는 argparse의 사용법을 본 파일을 통해 확인할 수 있었습니다.

tool.py 는 JSON의 validation, pretty print을 도와주는 커맨드라인 툴입니다.

사용예

1
2
3
4
5
6
7
$ echo '{"json":"obj"}' | python -m json.tool
{
"json": "obj"
}
$ echo '{ 1.2:3.4}' | python -m json.tool
Expecting property name enclosed in double quotes: line 1 column 3 (char 2)
"""

tool.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import argparse
import json
import sys


def main():
prog = 'python -m json.tool'
description = ('A simple command line interface for json module '
'to validate and pretty-print JSON objects.')
parser = argparse.ArgumentParser(prog=prog, description=description)
parser.add_argument('infile', nargs='?', type=argparse.FileType(),
help='a JSON file to be validated or pretty-printed',
default=sys.stdin)
parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'),
help='write the output of infile to outfile',
default=sys.stdout)
parser.add_argument('--sort-keys', action='store_true', default=False,
help='sort the output of dictionaries alphabetically by key')
parser.add_argument('--json-lines', action='store_true', default=False,
help='parse input using the jsonlines format')
options = parser.parse_args()

infile = options.infile
outfile = options.outfile
sort_keys = options.sort_keys
json_lines = options.json_lines
with infile, outfile:
try:
if json_lines:
objs = (json.loads(line) for line in infile)
else:
objs = (json.load(infile), )
for obj in objs:
json.dump(obj, outfile, sort_keys=sort_keys, indent=4)
outfile.write('\n')
except ValueError as e:
raise SystemExit(e)


if __name__ == '__main__':
main()
1
parser = argparse.ArgumentParser(prog=prog, description=description)

prog - 프로그램의 이름

description - 프로그램의 상세 내용 설명

1
2
3
4
5
6
7
8
9
10
11
12
13
$ python -m json.tool -h
usage: python -m json.tool [-h] [--sort-keys] [infile] [outfile]

A simple command line interface for json module to validate and pretty-print
JSON objects.

positional arguments:
infile a JSON file to be validated or pretty-printed
outfile write the output of infile to outfile

optional arguments:
-h, --help show this help message and exit
--sort-keys sort the output of dictionaries alphabetically by key

python -m : -m 플래그를 사용하면 파이썬의 라이브러리를 직접 실행 시킬 수 있습니다.

1
2
parser.add_argument(...)
options = parser.parse_args()

add_argument()를 통해 해당 프로그램이 처리 할 수 있는 인수를 추가합니다. 그리고 난 후 parse_args() 를 통해 입력받은 인수를 변수에 할당합니다.

1
2
3
4
5
6
7
8
9
10
11
with infile, outfile:
try:
if json_lines:
objs = (json.loads(line) for line in infile)
else:
objs = (json.load(infile), )
for obj in objs:
json.dump(obj, outfile, sort_keys=sort_keys, indent=4)
outfile.write('\n')
except ValueError as e:
raise SystemExit(e)

위 부분의 흐름을 보면 json.loads() 로 생성된 objsjson.dump() 하고 있습니다.

즉 문자열 입력을 받아 파이썬 오브젝트로 변환한 후 다시 파이썬 오브젝트를 파일에 직렬화하여 출력하고 있습니다.

이걸로 json 모듈 훑어보기가 끝났습니다.

감사합니다.