매개변수

클릭은 스크립트에서 두 가지 종류의 매개변수를 지원하는데, 옵션(option)과 인자(argument)다. 명령행 스크립트 작성자들 중에 이 둘을 헛갈리는 경우가 좀 있으니 차이점을 간단히 확인해 보자. 옵션은 이름 그대로 선택적이다. 인자는 일정 정도로 선택적일 수 있기는 하지만 선택적일 수 있는 방식에 훨씬 많은 제약이 있다.

옵션과 인자 중에 선택을 해야 하는 경우라면 하위 명령을 만들 때나 파일명/URL을 입력받는 경우 등에만 인자를 쓰고 그 외는 모두 옵션으로 하기를 권한다.

차이점

인자는 옵션보다 할 수 있는 게 적다. 다음 기능들은 옵션에서만 가능하다.

  • 빠진 입력을 자동으로 묻기.

  • 플래그로 동작하기. (불리언 또는 다른 방식)

  • 환경 변수에서 옵션 값을 가져올 수 있음. 인자는 안 됨.

  • 도움말 페이지에 옵션들은 모두 나오지만 인자는 나오지 않음. (이는 의도적인 것이다. 인자는 자동으로 표시하기에는 너무 상세할 수도 있다.)

한편으로 옵션과 달리 인자로는 임의 개수의 인자를 받을 수 있다. 옵션으로는 만약 받는다면 정확히 고정된 개수(기본 1)의 인자만 받을 수 있다.

매개변수 타입

매개변수 타입으로 여러 가지가 가능하다. 다른 동작 방식의 타입을 구현할 수 있고 기본적으로 지원하는 타입도 몇 가지 있다.

str / click.STRING:

기본 매개변수 타입이고 유니코드 문자열을 나타냄.

int / click.INT:

정수만 받는 매개변수.

float / click.FLOAT:

부동소수점 값만 받는 매개변수.

bool / click.BOOL:

불리언 값을 받는 매개변수. 불리언 플래그에는 자동으로 이 타입이 쓰인다. 문자열 값 1, yes, y, t, trueTrue로 변환되고 0, no, n, f, falseFalse로 변환된다.

click.UUID:

UUID 값을 받는 매개변수. 자동으로 이 타입으로 추측하지 않으며 uuid.UUID로 표현한다.

class click.File(mode='r', encoding=None, errors='strict', lazy=None, atomic=False)

매개변수를 읽기 또는 쓰기용 파일로 선언한다. 그 파일은 (명령 동작이 완료된 후) 문맥이 없어지면 자동으로 닫힌다.

파일을 읽기 또는 쓰기용으로 열 수 있다. 특수 값 -는 모드에 따라 stdin이나 stdout을 나타낸다.

기본적으로는 파일이 텍스트 읽기용으로 열리지만 바이너리 모드나 쓰기용으로 열 수도 있다. 그리고 encoding 매개변수를 써서 특정 인코딩을 강제할 수 있다.

lazy 플래그는 파일을 즉시 열지 아니면 첫 IO에서 열지를 제어한다. 기본 방식은 표준 입력 및 출력 스트림, 그리고 읽기용으로 여는 파일은 즉시 열고 그 외는 늦게 여는 것이다. 파일을 읽기용으로 늦게 열 때는 확인을 위해 잠깐 열기는 하되 첫 IO까지 열어두지 않는다. 늦게 여는 동작이 유용한 건 쓰기용으로 열면서 필요할 때까지는 파일이 생성되지 않게 할 때이다.

클릭 2.0부터는 파일을 원자적으로 열 수도 있는데, 그렇게 하면 모든 쓰기 내용이 같은 폴더 내의 별도 파일로 가며 작업이 끝나면 그 파일이 원래 위치로 옮겨지게 된다. 다른 사용자들이 규칙적으로 읽는 파일을 변경하는 경우에 유용하다.

더 자세한 내용은 파일 인자 참고.

class click.Path(exists=False, file_okay=True, dir_okay=True, writable=False, readable=True, resolve_path=False, allow_dash=False, path_type=None)

경로 타입은 File 타입과 비슷하되 다른 검사들을 수행한다. 우선 열린 파일 핸들을 반환하는 게 아니라 그냥 파일명을 반환한다. 그리고 그 파일 내지 디렉터리가 어떠해야 하는가에 대한 다양한 기본 검사를 수행할 수 있다.

Changed in version 6.0: allow_dash 추가됨.

Parameters
  • exists – 참으로 설정 시 이 값이 유효하려면 파일 내지 디렉터리가 존재해야 함. 이 조건을 지정하지 않고 파일이 실재 존재하지 않으면 이후 검사를 모두 조용히 건너뛴다.

  • file_okay – 파일이 가능한 값인지 여부를 지정.

  • dir_okay – 디렉터리가 가능한 값인지 여부를 지정.

  • writable – 참이면 쓰기 가능 여부 검사를 수행.

  • readable – 참이면 읽기 가능 여부 검사를 수행.

  • resolve_path – 참이면 경로를 완전히 해석하고 나서 값을 계속 전달함. 즉 절대 경로가 되고 심볼릭 링크들을 해석한다. 물결표 확장은 셸에서 할 일이므로 하지 않는다.

  • allow_dashTrue로 설정 시 대시 하나로 표준 스트림을 나타내는 걸 허용함.

  • path_type – 선택적. 경로를 나타내는 데 사용해야 할 문자열 타입. 기본은 None으로, 클릭에서 처리하는 입력 데이터가 어느 쪽에 맞는가에 따라 반환 값이 bytes 아니면 unicode가 된다.

class click.Choice(choices, case_sensitive=True)

선택 타입을 이용하면 값이 정해진 지원 값들 중 하나인지 확인할 수 있다. 지원 값들은 모두 문자열이어야 한다.

선택지들의 리스트나 튜플을 줘야 한다. (제너레이터 같은) 다른 이터러블은 예상치 못한 결과를 유발할 수 있다.

선택 옵션의 예시 참고.

Parameters

case_sensitive – 거짓으로 설정하면 선택지들이 대소문자 구분이 없게 됨. 기본은 참.

class click.IntRange(min=None, max=None, clamp=False)

click.INT와 비슷하게 동작하되 값을 어떤 범위로 제약하는 매개변수. 값이 범위를 벗어날 때 기본 동작은 실패하는 것이지만 두 경곗값 중 하나로 조용히 자를 수도 있다.

범위 옵션의 예시 참고.

class click.FloatRange(min=None, max=None, clamp=False)

click.FLOAT과 비슷하게 동작하되 값을 어떤 범위로 제약하는 매개변수. 값이 범위를 벗어날 때 기본 동작은 실패하는 것이지만 두 경곗값 중 하나로 조용히 자를 수도 있다.

범위 옵션의 예시 참고.

class click.DateTime(formats=None)

DateTime 타입은 날짜 문자열을 datetime 객체로 변환한다.

확인할 형식 문자열들을 설정할 수 있으며 몇 가지 많이 쓰는 (시간대 없는) ISO 8601 형식들이 기본값이다.

DateTime 형식을 지정할 때 리스트나 튜플을 줘야 한다. 제너레이터 같은 다른 이터러블은 예상치 못한 결과를 유발할 수 있다.

형식 문자열들은 datetime.strptime으로 처리되며, 그에 따라 허용되는 형식 문자열이 규정된다.

각 형식을 차례대로 사용해 파싱을 시도하며 파싱이 성공한 첫 번째 형식을 쓴다.

Parameters

formats – 시도 순서대로 된 날짜 형식 문자열들의 리스트 또는 튜플. 기본값은 '%Y-%m-%d', '%Y-%m-%dT%H:%M:%S', '%Y-%m-%d %H:%M:%S'.

click.ParamType의 하위 클래스를 만들어서 새로운 매개변수 타입을 구현할 수 있다. 더 간단하게는 실패 시 ValueError를 던지는 파이썬 함수를 전달하는 방식도 지원하지만 권하진 않는다.

매개변수 이름

매개변수(옵션과 인자 모두)는 정해진 수의 위치 인자들을 받으며 그 인자들은 명령 함수 매개변수로 전달된다. 대시 한 개가 있는 문자열은 짧은 인자로 추가되고 대시 두 개로 시작하는 문자열은 긴 인자로 추가된다.

대시 없이 추가하는 문자열은 내부 매개변수 이름이 되고 그 이름이 변수 이름으로도 쓰인다.

어떤 매개변수를 위한 이름들에 모두 대시가 있는 경우에는 가장 긴 인자를 골라 대시를 모두 밑줄로 바꿔서 자동으로 내부 이름을 만든다.

그리고 그 내부 이름을 소문자로 바꾼다.

예시:

  • 옵션에 ('-f', '--foo-bar')를 주면 매개변수 이름이 foo_bar다.

  • 옵션에 ('-x',)를 주면 매개변수가 x다.

  • 옵션에 ('-f', '--filename', 'dest')를 주면 매개변수 이름이 dest다.

  • 옵션에 ('--CamelCaseOption',)을 주면 매개변수가 camelcaseoption이다.

  • 인자에 (`foogle`)을 주면 매개변수 이름이 foogle이다. 도움말에 표시할 읽기 좋은 다른 이름을 주려면 도움말 잘라내기 절을 참고하라.

새로운 타입 구현하기

새로운 타입을 구현하려면 ParamType 클래스의 하위 클래스를 만들어야 한다. 타입 호출 시 문맥 및 매개변수 객체가 있을 수도 있고 없을 수도 있으며, 그래서 어느 쪽도 처리할 수 있어야 한다.

다음 코드는 일반 정수에 추가로 16진수와 8진수도 받아서 보통 정수로 바꿔 주는 정수 타입을 구현한 것이다.

import click

class BasedIntParamType(click.ParamType):
    name = 'integer'

    def convert(self, value, param, ctx):
        try:
            if value[:2].lower() == '0x':
                return int(value[2:], 16)
            elif value[:1] == '0':
                return int(value, 8)
            return int(value, 10)
        except ValueError:
            self.fail('%s is not a valid integer' % value, param, ctx)

BASED_INT = BasedIntParamType()

보다시피 하위 클래스에서 ParamType.convert() 메소드를 구현해야 한다. 선택적으로 ParamType.name 속성을 제공할 수 있는데, 문서화 용도로만 쓰인다.