본문 바로가기

개발/Python & Flask

Python Bash Stdout 인코딩 / import 경로 설정

DJ ango

다날 휴대폰 결제 연동 모듈 Python Django 버전으로 포팅했다.
이 과정에서 배운 부분을 정리한다.

stdout 인코딩

SClient 라는 C 로 짜여진 소켓통신 모듈을 사용한다.

파이썬에서 Bash 명령어 호출이 필요하다.

하지만 os.system("./SClient") 사용시 출력되는 한글을 읽어올 수 가 없었다.

파이썬 기본 인코딩은 UTF-8 인데 비해 자사 프로그램 출력은 EUC-KR 형태이기 때문

그래서 필요한 것은

  • stdout 을 읽어와야하고
  • 읽어온 stdout 을 인코딩해야했다.
Input = ClientModule+" \""+args+"\""
Output = subprocess.Popen(["/bin/bash", "-c", Input], stdout=subprocess.PIPE)
msg_content=""
for line in Output.stdout:
    l = line.decode(encoding="euc-kr", errors="ignore")
    msg_content += l
    Output.wait()
Output = msg_content

subprocess 는 os.system 을 대체하기 위해 만들어진 새로운 파이썬 기본 라이브러리 이다.

subprocess.popen 은 생성자이며 객체이다.

첫번째 인자로 bash 명령어를 list / str 형태로 받는다.

두번째 인자로 여러가지 인자를 선택할 수 있는데, stdout, stderr, stdin 에 대한 설정이 가능하다

  1. Output 에 subprocess.popen 객체가 담기고,
  2. subprocess.popen 속에 stdout 이 list 형태로 한 줄의 String 형태로 담긴다.
    한 줄의 String 이라면 이제 decode 함수를 적용할 수 있게 된다.
  3. 핵심은 Output.wait() 구문이다.
    파이썬의 메인 프로세스가 자식 프로세스의 output을 전부 읽을 때까지 기다리게 한다.
  4. 한줄 씩 문자열에 덧셈연산으로 이어주면 끝난다.

import 경로 설정

항상 조금씩 헷갈리고, 인터넷에선 각종 얘기들이 방법이 있었지만,

이렇게 하면 되지 않을까? 해서 혼자 찾아낸 방법이다.

같은 디렉터리일 경우

# onefile.py, py 생략
from . import onefile

한 서브 디렉터리일 경우

from .subdir import onefile

디렉터리 바깥일 경우

from ..outdir import onefile
# 예상했겠지만 그냥 이렇게 호출하면 에러
# 까다롭지만 python -m 모듈옵션과 패키지정보가 포함된 형태로 호출해야한다.
# 어길 시 ValueError: attempted relative import beyond top-level package 가 발생
# 여기에 아주 잘 정리됨 : https://m.blog.naver.com/wideeyed/221839634437

Git : https://github.com/gogoonbuntu/TeleditClientDjango

반응형