편리한 코딩을 위한 Python 알쓸신잡

 · 5 mins read

지난 번에 자연어처리에 필요한 python 함수와 팁들을 정리했었는데 다른 사람들은 보는지 안 보는지 모르겠지만 내가 계속 들오가서 보게 된다;;ㅋㅋㅋ 사실상 나를 위해 쓰긴 했으니 상관은 없지만… 그래서 오늘은 또 다시 내가 자주 쓰는 아니면 새로 발견한 편리한 function들에 대해서 포스팅을 하려고 한다. 근데 이번에는 자연어 처리 작업에 한정되지 않고 그냥 코드를 좀 더 깔끔하게? 효율적으로? 사용할 수 있는 방법들 위주로 포스팅.

1. func_argparse

Source: https://github.com/gwenzek/func_argparse

이건 fairseq laser을 사용하면서 알게 된 함수. 갑자기 func_argparse 라는 걸 import 하길래 뭐지… 그냥 기본 파이썬 패키지인가?하고 import를 해봤지만 역시 안된다. pip install func_argparse를 하니 다운로드가 시작된다. 구글링을 해보니 위에 링크해둔 깃헙을 찾았다.

개인이 만든 패키지인 거 같은데 써보니까 굉장히 유용하다. func_argparse를 통해서 python document안에 있는 함수를 부르고, 함수에 argument를 패싱해줄 수 있다. 아래는 깃헙에 나와 있는 예시:

hello.py

"""Say hello or goodbye to the user."""

import func_argparse


def hello(user: str, times: int = None):
    """Say hello.

    Arguments:
        user: name of the user
    """
    print(f"Hello {user}" * (1 if times is None else times))


def bye(user: str, see_you: float = 1.0):
    """Say goodbye."""
    print(f"Goodbye {user}, see you in {see_you:.1f} days")


if __name__ == "__main__":
    func_argparse.main()

CLI

$ python hello.py hello --user gwenzek
Hello gwenzek

$ python hello.py hello --user gwenzek --times 2
Hello gwenzekHello gwenzek

$ python hello.py bye --user gwenzek --see_you 12.345
Goodbye gwenzek, see you in 12.3 days

$ python hello.py hello -u gwenzek -t 1
Hello gwenzek

$ python hello.py --help
usage: hello.py [-h] {hello,bye} ...

Say hello or goodbye to the user.

positional arguments:
  {hello,bye}
    hello      Say hello.
    bye        Say goodbye.

optional arguments:
  -h, --help   show this help message and exit

$ python hello.py bye --help
usage: hello.py bye [-h] -u USER [-s SEE_YOU]

optional arguments:
  -h, --help            show this help message and exit
  -u USER, --user USER
  -s SEE_YOU, --see_you SEE_YOU
                        (default=1.0)

그러니까 main에 어떤 함수를 사용할 건지 따로 명시를 안해놔도 CLI에서 컨트롤 할 수 있다! 하나의 .py 파일에 여러 잡다구리한 함수를 저장해놓고 필요한 함수를 CLI에서 불러 올 수 있기 때문에 편리하다. 나도 다음에 코드에 사용해봐야겠다.

2. print(‘\r’)

이건 나만 모르고 있었던 기능인가…? ㅎㅎ 간단한 코드 쓸 때 아니면 디버깅할 때 코드의 진행사항이나 어디서 에러 났는지 알고 싶으면 그냥 print()를 사용했는데, 긴 for loop 안에 있으면 아웃풋이 굉장히 길어져서 보기도 어렵고 지저분하다.

근데 print() 함수 안에 \r를 넣어주면 “carriage return”을 의미하며 cursor을 그 라인의 맨 앞으로 돌려준다. 무슨 뜻이냐면 전에 아웃풋을 overwrite할 수 있다. 같은 라인에 계속 값이 출력된다. 그래서 에러가 어딨는지 찾고 싶은데 여기 저기 프린트를 넣어줬다면 맨 마지막에 에러난 곳을 한 줄에 출려해준다는 뜻.

무슨 소린지 정말 나만 알아 듣게 써놓은 거 같다… 그리고 사실 그렇게 중요한 기능은 아닌데 CLI에서 출력이 적어지기 때문에 더 깔끔하다. 중요한건 print 함수의 end 파라미터를 꼭 ''로 설정해줘야된다. 디폴트는 '\n'인데, 사실 그렇게 되면 그냥 \r 없이 출려하는 것과 똑같이 된다.

논외로 이 기능에 대해서 조금 구글링 하니까 로딩되는 애니메이션? 같은 것도 이걸 사용해서 만든다고 하더라. 이런거:

animation

Source: https://realpython.com/python-print/

from itertools import cycle
from time import sleep

for frame in cycle(r'-\|/-\|/'):
    print('\r', frame, sep='', end='', flush=True)
    sleep(0.2)

써보니까 정말 좀 쓸데없는 건데… 코드를 더 아름답게(?ㅋㅋ) 쓸 수 있는 방법. 그것도 중요하지…

3. flatten

코딩 하다 보면 list of list가 생기는 경우가 꽤 자주 있다. 근데 이걸 그냥 하나의 리스트로 만들고 싶다면?

flatten = lambda t: [item for sublist in t for item in sublist]

이 함수를 사용하면 된다. 너무 간단한 솔루션인데 막상 그냥 하려고 하면 생각이 잘 안난다. 나도 자주 사용하는 함수인데 항상 구글링해서 찾아본다;;ㅎㅎ 그래서 블로그에 박재. lambda를 사용해서 함수를 만드는 방법에 대해서는 좀 논란이 있는 걸로 알고 있다. 나도 자주 사용하지는 않지만 이렇게 간단한 한 줄로 쓸 수 있는 코드는 lambda를 사용해도 나쁘지 않은 것 같다.

Source: https://stackoverflow.com/questions/952914/how-to-make-a-flat-list-out-of-a-list-of-lists

4. pip install –no-deps package-name

이건 사실 엄밀히 말하자면 파이썬은 아니지만 이번에 알게된 유용한 정보. pip install package-name을 할 때 가끔 Packages installed from PyPI cannot depend on packages which are not also hosted on PyPI이런 에러 메시지가 뜬다. Dependency 패키지 다운로드에 무슨 문제가 있다는 건데… 그래서 패키지를 따로 다운 받아야되나 어떻게 해야되나 이러다가 구글링을 하니까 더 쉬운 솔루션을 찾았다.

pip install --no-deps package-name
pip install package-name

--no-deps 로 먼저 패키지를 다운 받은 다음에 pip install하면 패키지가 정상적으로 잘 다운된다… 왜인지는 모르겠다. 언잰간 다시 유용할 것 같아서 포스트에 써본다.

Source: https://discuss.python.org/t/packages-installed-from-pypi-cannot-depend-on-packages-which-are-not-also-hosted-on-pypi/3736/5

또 막상 써보니까 별거 없다… ㅎㅎ 구글링 못하는 시절에 코딩을 한 사람들이 진정한 천재들 같다. 요즘은 사실 구글링만 잘 해도 코딩 잘 할 수 있는 거 같다. 구글에 어떤 키워드를 넣어서 서칭을 해야되는지 아는 게 패키지나 함수를 암기하는 것 보다 더 중요할 수도 있다.