paramter, argument 그리고 torch.randint(미해결)

한재민·2023년 5월 14일
0
post-custom-banner

목적

  • 파이썬 함수의 parameter, argument 정리하기
  • torch.randintlow parameter 분석하기

Parameter, Argument

파이썬에서 함수를 정의하는 예시를 들어보자.

def print_params(a, b=3):
    print(a, b)

print_params 선언에서 소괄호 내부에 사용된 a, b 가 이 함수의 parameter 이다. a는 함수를 호출할 때 필수적인 parameter 이므로 required parameter 이고, b는 호출 시 생략되어도 default 값인 3 이 할당됨으로 optional patameter 이다.

print_params(3, b=5)
# 3, 5

함수를 호출함에 있어 괄호 안에 3, b=5 가 들어가 있는 모습을 볼 수 있다. 이렇게 함수가 호출되기 위해 전달되는 것들을 argument 라 한다.
3 은 첫 번째 argument이고, 이에 따라 첫 번째 paramter 인 a 에 할당된다. 따라서 3positional argument 라 한다.
반면 b=5 는 함수의 b 라는 parameter에 keyword 형태로 할당되므로 이를 keyword argument라 한다.

여기까지 보면 required paramter == positional argument고,
optional paramter == keyword argument 라고 생각할 수 있다.

하지만 paramter 는 함수 선언 시에 사용되는 개념이고, argument 는 호출 시에 사용되는 개념이기 때문에 둘을 구분할 필요가 있다.

print_params(b=5, a=3)
# 3, 5

위에서는 b=5, a=3 모두 keyword argument 로 사용되었고,

print_params(3, 5)
# 3, 5

여기서는 3, 5 모두 positional argument 로 사용되었다.

Order of Pamameter, Argument

함수를 선언할 떄 optional parameter 는 requred parameter 보다 앞에 위치할 수 없다.

def print_params(b=3, a):
    print(a, b)

# 에러 발생!
# SyntaxError: non-default argument follows default argument    

비슷하게 함수를 호출할 때 keyword argument 는 positional argument 보다 앞에 위치할 수 없다.

print_params(b=3, 5)

# 에러 발생!
# SyntaxError: positional argument follows keyword argument

근데 얘는 뭐임?

pytorch 의 randint 함수의 doc을 보다 이상한 점을 발견했다.

torch.randint

torch.randint(low=0, high, size, *, generator=None, out=None, dtype=None, layout=torch.strided,
device=None, requires_grad=False) → Tensor

(중간의 * 기호는 그 뒤의 parameter 는 호출 시 모두 keyword argument이여야 함을 의미한다.)

doc의 설명만 보면, low 는 optional 이고, 실제로 잘 작동한다. 하지만 분명 optional은 required 보다 뒤쪽에 위치해야 하는데, 뭔가 잘못된 것일까?

torch.randint() 코드를 그대로 실행해 보면 다음과 같은 error message를 볼 수 있다.

TypeError: randint() received an invalid combination of arguments - got (), but expected one of:

  • (int high, tuple of ints size, *, torch.Generator generator, Tensor out, torch.dtype dtype, torch.layout layout, torch.device device, bool pin_memory, bool requires_grad)
  • (int high, tuple of ints size, *, Tensor out, torch.dtype dtype, torch.layout layout, torch.device device, bool pin_memory, bool requires_grad)
  • (int low, int high, tuple of ints size, *, torch.Generator generator, Tensor out, torch.dtype dtype, torch.layout layout, torch.device device, bool pin_memory, bool requires_grad)
  • (int low, int high, tuple of ints size, *, Tensor out, torch.dtype dtype, torch.layout layout, torch.device device, bool pin_memory, bool requires_grad)

randint 함수는 네 가지 종류의 input에 대해 동일한 출력을 낼 수 있게 구현된, 일종의 다형성(Polymorphism)을 갖고 있는 함수라고 볼 수 있다.

실제로 아무리 개떡같이 호출해도 잘 작동하는 모습을 확인할 수 있다.

torch.randint(0, 5, (2, 2))

torch.randint(5, (2, 2))

torch.randint(low=0, high=5, size=(2, 2))

torch.randint(high=5, size=(2, 2))

torch.randint(size=(2, 2), high=5)

torch.randint(high=5, size=(2, 2), low=0)

torch.randint(size=(2, 2), low=0, high=5)

torch.randint(0, size=(2, 2), high=5)

# 모두 같은 같은 동작을 한다.

그래서 이러한 다형성을 어떻게 구현한건지 알아보고자 source code를 뒤져보았지만, 코드가 꼬리에 꼬리를 무는 형태라 바로 이해하기가 힘들었다. 일단 parameter와 argument에 대해 정리한 것에 의의를 두고, 이후에 다시 정리해보자.

profile
열심히 하는 사람
post-custom-banner

0개의 댓글