파이썬 dictionary를 Json형식으로 저장할 때 Escape Sequence 문제 해결
오류 상황
File을 List 자료형으로 Read한 후에
List에 저장되어있는 Data를 Dictionary 자료형의 value로 저장한 뒤
Dictionary 자료형을 json 형식으로 파일 저장하기 위해
import json 또는 pickle을 사용하면 Escape Sequence 문제가 발생함.
문제 상황 예제
1. test.log 파일에 아래와 같은 데이터가 있음.
"/bin/grep hfsplus | /bin/awk \'{print} END {if (NR == 0) print \"pass\" ; else print \"fail\"}\'"
2. 해당 파일을 읽어서 List에 저장함.
file = open('./test.log', 'r', encoding='utf-8')
temp = []
while True:
line = file.readline()
if not line: break
temp.append(line)
file.close()
3. List의 data를 dictionary의 value로 저장함.
key = test
value = file에서 읽어온 후 list에 저장되어있는 data
testdictionary = {}
testdictionary["test"] = temp[0]
4. json 라이브러리를 사용해서 해당 dictionary를 json 형식으로 file write함.
import json
with open('./testJson.log', 'w', encoding='utf-8') as outFile:
json.dump(testdictionary, outFile, indent="\t")
5. 결과 확인
origin의 경우 아래와 같은데
\'{print} END {if (NR == 0) print \"pass\" ; else print \"fail\"}\'
import json을 사용해서 json 형식으로 저장할 시
"\\'{print} END {if (NR == 0) print \\\"pass\\\" ; else print \\\"fail\\\"}\\'"
이렇게 파이썬에서 dictionary형식 File저장 시 json라이브러리 사용하면
Escape Sequence를 위와같이 한번 더 처리해서 저장하는 현상이 있었음.
파이썬에서 제공하는 pickle, json 모두 동일한 증상을 가지고 있음.
해결법
해당 문제를 해결하기 위해
dictionary type을 json으로 저장 시
Escape Sequence를 그대로 유지하는 함수를 직접 개발함.
코드는 아래와 같음.
코드
def debugLogJsonType_EscapeSequenceOrigin(fileName, path, log):
if not os.path.isdir(path):
os.mkdir(path)
path += "/"
tabCount = 1
try:
with open(path + fileName,'w') as file:
file.write('{\n')
count = 1
checkLast = False
for key, value in log.items():
if len(log) == count :
checkLast = True
file.write('\t')
if "<class 'list'>" == str(type(value)) :
file.write('"%s": ' % (key) )
debugLogJsonType_IfList(file, value, tabCount, checkLast)
elif "<class 'dict'>" == str(type(value)) :
file.write('"%s": ' % (key) )
debugLogJsonType_IfDict(file, value, tabCount, checkLast)
else :
if False == checkLast :
file.write('"%s": "%s",\n' % (key, value))
else :
file.write('"%s": "%s"\n' % (key, value))
count = count + 1
file.write('}')
file.close()
except (Exception) as e:
print(f"except : {e}")
def debugLogJsonType_IfList(file, log, tabCount, checkLastRoot):
file.write('[\n')
tabCount = tabCount + 1
checkLast = False
for number in range(len(log)):
data = log[number]
if len(log) -1 == number :
checkLast = True
debugLogJsonType_WriteTab(file, tabCount)
if "<class 'list'>" == str(type(data)) :
debugLogJsonType_IfList(file, data, tabCount, checkLast)
elif "<class 'dict'>" == str(type(data)) :
debugLogJsonType_IfDict(file, data, tabCount, checkLast)
else :
if False == checkLast :
file.write('"%s",\n' % (data))
else :
file.write('"%s"\n' % (data))
debugLogJsonType_WriteTab(file, tabCount-1)
if False == checkLastRoot :
file.write('],\n')
else :
file.write(']\n')
def debugLogJsonType_IfDict(file, log, tabCount, checkLastRoot):
file.write('{\n')
tabCount = tabCount + 1
count = 1
checkLast = False
for key, value in log.items():
if len(log) == count :
checkLast = True
file.write('\t')
if "<class 'list'>" == str(type(value)) :
debugLogJsonType_WriteTab(file, tabCount-1)
file.write('"%s": ' % (key) )
debugLogJsonType_IfList(file, value, tabCount, checkLast)
elif "<class 'dict'>" == str(type(value)) :
debugLogJsonType_WriteTab(file, tabCount-1)
file.write('"%s": ' % (key) )
debugLogJsonType_IfDict(file, value, tabCount, checkLast)
else :
debugLogJsonType_WriteTab(file, tabCount-1)
if False == checkLast :
file.write('"%s": "%s",\n' % (key, value))
else :
file.write('"%s": "%s"\n' % (key, value))
count = count + 1
debugLogJsonType_WriteTab(file, tabCount-1)
if False == checkLastRoot :
file.write('},\n')
else :
file.write('}\n')
def debugLogJsonType_WriteTab(file, tabCount):
count = 0
while count < tabCount :
file.write('\t')
count = count + 1
사용법
debugLogJsonType_EscapeSequenceOrigin('test_MyJson.log', './', subRuleResult)
결과
{
"test": "/sbin/lsmod | /bin/grep hfsplus | /bin/awk \'{print} END {if (NR == 0) print \"pass\" ; else print \"fail\"}\'"
}
위와 같이 Escape Sequence 가 origin과 동일하게 저장됨.
주의
debugLogJsonType_EscapeSequenceOrigin 를 사용해서 json 형식으로 File write한 후
다시 import json를 사용해서 아래 코드로 저장했던 json파일을 읽어오면
with open(filePath, 'r', encoding='utf-8') as outFile:
result = json.load(outFile)
위와 같이
json.decoder.JSONDecodeError: Invalid \escape: line 2 column 54 (char 55)
오류가 발생함.
해당 오류 원인인 json file write 시 Escape Sequence 처리를 하고 저장하고
읽어올 시 다시 Escape Sequence 처리를 하고 읽어오는데
json 패키지에서 읽어올 때 Escape Sequence 문제가 있다고 판단해서 오류가 발생함.
즉 debugLogJsonType_EscapeSequenceOrigin 로 생성한 json 파일은
import json 으로 file read하진 못함.
'코딩 > Python' 카테고리의 다른 글
VSCode 오류 해결 : The python path in your debug configuration is invalid (0) | 2021.07.10 |
---|---|
python 개념 정리 (0) | 2021.06.06 |
python3 version 으로 update 후 yum 에러 해결법 (0) | 2021.06.06 |