본문 바로가기

Language/Python

RePythonOOP 15일차 Python Multi Parameter Variables, Function Signature, Function Partial

Insight

1.  다양한 매개변수들의 형식에 맞게 인자를 처리할 수 있게 되었다.

2.  파라미터의 정보들이 햇갈릴 때 Signature를 사용 할 줄 안다.

3. 함수내 특정한 인자를 고정해야 할 때 Partial을 사용 할 줄 안다. 

다양한 매개변수들 입력시 파이선의 처리방법

 

일반 파라미터, 가변 파라미터, 디폴트 파라미터, 키워드 파라미터 순서대로 알아 보겠습니다.

 

def test(id, *args, age=None, **kwargs):
    return 'test ({}) ({}) ({}) ({})'.format(id, args, age, kwargs)

 

 

아이디 매개변수로만 받는다.

 

print(test('test1'))
# test (test1) (()) (None) ({})

 

아이디 매개변수 먼저 붙이고 나머지는 튜플로 가변인자로

 

 

print(test('test1', 'test2'))
# test (test1) (('test2',)) (None) ({})

 

아이디 매개변수 먼저 붙이고 나머지는 튜플로 가변인자로

 

print(test('test1', 'test2', 'test3'))
# test (test1) (('test2', 'test3')) (None) ({})

 

아이디 매개변수 먼저 붙이고 나머지는 튜플내 리스트 가변인자로

 

print(test('test1', ['test2', 'test3']))
# test (test1) ((['test2', 'test3'],)) (None) ({})

 

아이디 매개변수 먼저 붙이고 나머지는 튜플로 가변인자로 age 디폴트값 변함

 

print(test('test1', 'test2', 'test3', age=7))
# test (test1) (('test2', 'test3')) (7) ({})

 

아이디 매개변수 먼저 붙이고 나머지는 튜플로 가변인자로 age 디폴트값 변함 name은 없는 파라미터로 키워드 인자 처리

 

print(test('test1', 'test2', 'test3', age=7, name='abc'))
# test (test1) (('test2', 'test3')) (7) ({'name': 'abc'})

 

'test4' 같은 경우 가변인자로 처리되어야 하는데 키워드 인자 뒤에있으므로 순서를 지켜줘야 한다.

 

# print(test('test1', 'test2', 'test3', age=7, name='abc', 'test4'))
# SyntaxError: positional argument follows keyword argument

 

정확하게 파라미터들의 순서를 지켜준 예

 

print(test('test1', 'test2', 'test3', age=7, password='1234', name='abc'))
# test (test1) (('test2', 'test3')) (7) ({'password': '1234', 'name': 'abc'})

 

중요한 것은 파이썬에서의 인자 처리는

 

값만 인자로 넣을경우 가변인자(튜플) 처리합니다.

 

값이 아닌 키 벨류 형식으로 줄시 키워드 인자(딕셔너리) 처리합니다.

 

 

Function Signature

 

함수 내의 파라미터들의 정보(이름, 종류, 디폴트값)들을 볼 수 있다.

 

from inspect import signature

sg = signature(test)

print(sg)
# (id, *args, age=None, **kwargs)
print(sg.parameters)
# 더 자세히 파라미터의 정보를 볼수있다.
# OrderedDict([('id', <Parameter "id">), ('args', <Parameter "*args">), ('age', <Parameter "age=None">), ('kwargs', <Parameter "**kwargs">)])

# 모든 정보 출력하려면 for문으로 items()의 name 과 param의 kind와 default가 있는지 없는지 확인 가능하다.
for name, param in sg.parameters.items():
    print("name: ", name, "kind: ", param.kind,"default :", param.default)
# name:  id kind:  POSITIONAL_OR_KEYWORD default : <class 'inspect._empty'>
# name:  args kind:  VAR_POSITIONAL default : <class 'inspect._empty'>
# name:  age kind:  KEYWORD_ONLY default : None
# name:  kwargs kind:  VAR_KEYWORD default : <class 'inspect._empty'>
# sql의 컬럼 정보와 많이 닮아 있다.

 

Function Partial

partial : 인자를 하나의 값으로 고정하기 위해서 사용한다.

주로 특정 인수 고정 후 콜백 함수에서 사용한다.

 

콜백 함수는 일급함수(first-class function)내에 포함된

일급 시민의 기능중 "함수 인수 전달 가능"과 같다.

 

파이썬과 비슷한 JS MDN자료를 참조해서 파이썬의 구조와 비교해 본 결과 내린 결론이여서 틀릴 수도 있다.

(그래도 구조적으로 보았을때 맞는거 같다.)

https://developer.mozilla.org/ko/docs/Glossary/First-class_Function

 

from operator import mul
from functools import partial

print(mul(5,5))
# 굳이 5*5를 쓰지 않는 것은
# prtial()함수로 mul 함수를 첫 번째 인자로 받기 위해서

# prtial 인자 고정하는 함수
five = partial(mul, 5)
# 5 * ?와 같이 첫번째 인자를 고정할수있다.

# 두번째 변수 고정 추가를 파티션 함수로 받아서 또 쓸 수 있다.
five_second = partial(five, 5)

print(five(5)) # 인자 2개중 첫번째만 5로 고정되있고 뒤에 인자를 5를 넣음 # 25
print(five_second()) # 25

# 아래처럼 리스트 컴프리핸션도 가능하다.
print([five(i) for i in range(1,11)]) # [5, 10, 15, 20, 25, 30, 35, 40, 45, 50]
print(list(map(five, range(1,11))))   # [5, 10, 15, 20, 25, 30, 35, 40, 45, 50]