파이썬 강좌 – 다양한 함수 인수 ~ 유연한 함수 만들기

  1. 프롤로그
  2. 개발 첫걸음
    1. 컴퓨터 구성요소 - 컴퓨터는 어떤 걸 할 수 있나?
    2. 개발과 관련된 용어
    3. 파이썬의 선택 - 왜 파이썬인가?
    4. 파이썬 설치 - Hello World 출력하기
    5. Visual Studio Code 의 편리한 기능
    6. REPL과 콘솔 창 - 파이썬 동작시키기
  3. 파이썬 기초
    1. 기초 입출력 - 소통하기
    2. 변수와 대입 - 기억하기
    3. 연산자 - 계산하기
    4. 조건문 - 분기를 만들기
    5. 반복문 - 비슷한 작업을 반복하기
    6. 변수와 리스트 - 비슷한 변수들을 묶기
    7. for, range - 리스트의 항목을 다루기
    8. 파이선 기초 꿀팁
      1. 함수와 메소드의 호출 - 편리한 기능 이용하기
      2. 모듈 설치와 사용 - 유용한 기능 끌어다 쓰기
      3. 문자열 - 텍스트 다루기
  4. 파이썬 중급
    1. 정규표현식 - 문자열을 검색하고 치환하기(작성중)
    2. 함수를 직접 만들기 - 자주 쓰는 기능을 묶기
    3. 딕셔너리, 튜플, 세트 - 변수를 다양한 방법으로 묶기
    4. 클래스와 객체 - 변수를 사람으로 진화시키기
    5. 상속 - 클래스를 확장하기
    6. 파이썬 중급 꿀팁
      1. 코드를 작성하는 사람의 의도(작성중)
      2. 정체성과 동질성 - 객체의 성질(작성중)
      3. 명령문, 표현식 - 문법을 이루는 것들 (작성중)
      4. 슬라이싱 - 리스트를 갖고 놀기
  5. 파이썬 고급
    1. 예외와 에러 - 예상치 못한 상황에 대응하기
    2. 특별 메소드와 연산자 - 파이썬의 내부 작동방식 이해하기
    3. 다양한 함수 인수 - 유연한 함수 만들기
    4. 시퀀스와 반복자 - 반복과 순회를 자유자재로 다루기
    5. 변수의 범위 - 이름 검색의 범위
  6. 파이썬 심화
    1. 제너레이터와 코루틴 -
    2. async와 await
    3. 데코레이터 - 함수의 기능을 강화하기
    4. 객체로서의 클래스 - 클래스를 동적으로 정의하기
  7. 파이썬 프로젝트 실습
    1. 원카드 게임 만들기 (1)
    2. 원카드 게임 만들기 (2)
  8. 실전 (파이썬 외적인 것들)
    1. 유니코드 - 컴퓨터에서 문자를 표기하는 방법
    2. html, css, 인터넷 - 자동화 첫 걸음 내딛기
    3. 네트워크 - 인터넷으로 통신하는 방법
    4. 문서 - 문맥을 읽어보기


기본값(default) 지정

파이썬에서는 함수를 호출할 때 인수가 적절하게 들어가있어야 합니다. 하지만 기본값이 정해진 인수는 함수 호출 시 생략하여도 무방합니다. 기본값을 설정하는 방법은 함수 정의 시 변수명=값 으로 작성하는 것입니다. (함수 호출시 등호(=)를 이용하는 건 또 다른 개념입니다.) 다음 예제를 참고해주세요.

def say_hi(a='철수', b=10, c=20):
    print('안녕 ' + str(a) + '야, ' + '나는 ' + str(b) + 
        '살이고 내 형은 ' + str(c) + '살이야.')

say_hi()
say_hi('영미')
say_hi('영미', 15)
say_hi('영미', 15, 25)

다음은 결과입니다.

안녕 철수야, 나는 10살이고 내 형은 20살이야.
안녕 영미야, 나는 10살이고 내 형은 20살이야.
안녕 영미야, 나는 15살이고 내 형은 20살이야.
안녕 영미야, 나는 15살이고 내 형은 25살이야.

기본값을 넣은 인수 이후에는 기본값이 없는 인수가 등장할 수 없습니다. 아래와 같은 코드를 사용하게 되면 함수 정의 단계에서 에러가 발생합니다.

def say_hi(a='철수', b, c=20):
    print('안녕 ' + str(a) + '야, ' + '나는 ' + str(b) + 
        '살이고 내 형은 ' + str(c) + '살이야.')
  File "c:/Users/tooth/Desktop/test.py", line 1
    def say_hi(a='철수', b, c=20):
              ^
SyntaxError: non-default argument follows default argument

b는 기본값이 없으므로 무조건 채워야 하는데, b의 위치는 두번째입니다. 즉 b의 내용을 채워넣으려면 첫번째인 a 또한 매번 인수로 값을 받을 수 밖에 상황이기에 adefault는 사실상 필요가 없어집니다. 이러한 설계상의 결함을 최소화하기 위해 아예 에러로 처리하는 파이썬 인터프리터의 모습을 확인할 수 있습니다. (추가 예정)


가변 인수 (variadic arguments)

파이썬은 가변 인수를 활용할 수 있습니다. 가변 인수란 "인수의 개수가 변할 수 있다"라는 뜻입니다. 특징은 다음과 같습니다.

  • 변수명 바로 앞에 별표(*)만 첨가하여 바로 사용할 수 있습니다.
  • 함수 내에서 튜플(tuple) 로 제공됩니다.
  • 기본값을 지정할 수 없습니다.
  • 함수에 하나에 최대 하나만 존재합니다. def example(a, *b, *c):와 괕이 정의하면 바로 에러가 발생합니다.
  • 함수를 호출할 때 가변 인수에 값이 하나도 전달되지 않아도 됩니다.
def example(apple, banana, *stuff):
    print(apple, banana, stuff)
example('철수', '영미')
example('철수', '영미', '진수', '나영', '태현')
철수 영미 ()
철수 영미 ('진수', '나영', '태현')

위 예제에서 stuff는 인수가 나열된 튜플입니다. 우리는 for 가등을 이용하여 인수를 활용해볼 수 있을 것입니다.


위치 인수와 키워드 전용 인수

이 용어는 전문가를 위한 파이썬의 번역본을 그대로 가져왔습니다.

위치 인수(positional argumnet) 란 함수에게 인수를 전달할 때 첫 번째 위치, 두 번째 위치 등 위치 기반으로 전달되는 인수입니다. 모든 위치 인수는 키워드로서 전달할 수 있습니다. 키워드로서 전달하는 방법은 함수 호출 시 인수를 적을 때 인수명=값과 같이 작성하면 됩니다. 아래 예시를 참고해주세요.

def example(apple, banana):
    print(apple, banana)
example('철수', '영미')
example(banana='철수', apple='영미')
철수 영미
영미 철수

키워드 인수와 위치 인수는 혼합하여 사용할 수 있습니다. 다만 함수 호출 시 키워드로서 인수 전달은 반드시 위치 인수 뒤에 있어야 합니다. 다음 예제를 참조해주세요.

def example(apple, banana):
    print(apple, banana)
# example(banana='철수', '영미')
# 설명 : 에러입니다. 키워드 인수 전달은 반드시 위치 인수보다 뒤에 있어야 합니다.

# example('철수', apple='영미')
# 설명 : 에러입니다. 첫번째 두번째 모두 apple 인수를 가리키고 있습니다.

example('철수', banana='영미') 
# 설명 : 성공입니다.
철수 영미

키워드 전용 인수(keyword-only argumnet) 는 결코 위치 기반으로 전달될 수 없는 인수를 뜻합니다. 특징은 다음과 같습니다.

  • 키워드 전용 인수로 설정하는 방법은 크게 어렵지 않습니다. 별표(*) 뒤에, 즉 가변 위치 인수 뒤의 것들은 모두 키워드 전용이 됩니다.
  • 기본값(default)를 지정해도 되고 지정하지 않아도 됩니다.
  • 위치 인수와 달리 기본값이 있는 것과 없는 것 사이의 순서는 상관이 없습니다.
def example(apple, banana, *stuff, magic='마술', car):
    print(apple, banana, stuff, car, magic)

# example('철수', '영미')
# 설명: 에러입니다. car을 무조건 지정해야 합니다.

# example('철수', '영미', '진수', '나영', '태현') 
# 설명: 에러입니다. 가변 인수는 모두 stuff로 들어가기 때문에 
# 마찬가지로 car이 지정되지 않았습니다.

example('철수', '영미', '진수', '나영', '태현', car='포르쉐') 
# 설명: 성공적입니다.
철수 영미 ('진수', '나영', '태현') 포르쉐 마술

가변 인수 없는 키워드 전용 인수

가변 인수 없이 키워드 전용 인수를 사용하고 싶다면, 별표(*)만 하나 들어간 인수를 설정해주면 됩니다.

def f(a, *, b):
    print(a + b)

f(1, b=2)
# f(3, 4) ## 에러입니다. b는 무조건 키워드로 접근해야 합니다.
3

키워드 전용 가변 인수

키워드 전용 인수 또한 가변 인수를 설정할 수 있습니다. 방법은 위치 가변 인수와 비슷한데, 별표(*) 하나가 아니라 두개(**)를 변수명 앞에 붙여주면 됩니다. 특징은 다음과 같습니다.

  • 함수 내에서 딕셔너리(dictionary) 로 제공됩니다.
  • 마찬가지로 기본값을 지정할 수 없습니다.
  • 마찬가지로 함수에 하나에 최대 하나만 존재합니다. def example(a, **b, **c):와 같이 정의하면 바로 에러가 발생합니다.
  • 위치 가변 인수와 함께 사용할 수 있습니다. def example(a, *b, **c):는 문제 없습니다.
  • 위치 가변 인수 뒤에 존재해야 합니다. def example(a, **b, *c):는 에러입니다.
  • 뒤에 키워드 전용 인수가 올 수 없습니다. def example(a, *b, **c, d=10)는 에러를 일으킵니다.
  • 함수를 호출할 때 가변 인수에 값이 하나도 전달되지 않아도 됩니다.

아래는 예시입니다.

def example(apple, banana, **stuff):
    print(apple, banana, stuff)
example('철수', '영미')

# example('철수', '영미', '민수')
# 설명 : 위치 인수는 가변 인수 없이 2개만 
# 받고 있으므로 '민수'는 갈 데가 없어서
# 에러가 발생합니다.

example('철수', '영미', smart='민수')
철수 영미 {}
철수 영미 {'smart': '민수'}

위치 전용 인수

2019년 10월 14일 업데이트 된 파이썬 3.8에서 새롭게 추가된 내용입니다. 기본적으로 인수는 위치 인수이고, 키워드를 통해서도 접근할 수 있다고 하였습니다. 하지만 위치로만 접근할 수 있고 키워드로는 접근할 수 없도록 제한하는 방법이 새로이 등장했습니다. 그것은 위치 인수 사이에 /라는 인수를 추가하는 것입니다. /를 기준으로 왼쪽에 있는 변수들은 모두 위치 전용 인수가 됩니다.

def f(a, b, /, c, d, *, e, f):
    print(a, b, c, d, e, f)
# a, b는 위치 전용 인수이고 c, d는 일반 위치 인수이고 e, f는 키워드 전용 인수입니다.

f(10, 20, 30, d=40, e=50, f=60)
# 올바른 사용입니다. 

f(10, b=20, c=30, d=40, e=50, f=60)
# 에러입니다. b는 키워드로 접근할 수 없습니다.

f(10, 20, 30, 40, 50, f=60)   
# 에러입니다. e는 위치 기반으로 접근할 수 없습니다.

위치 전용 인수는 일반 사용자보다는 라이브러리 설계자가 이용하도록 고안된 것이며 우리가 함수를 정의할 때 이를 사용하는 일은 드물 것입니다. 하지만 파이썬 표준에 포함된 만큼 어떤 라이브러리가 /를 사용한다고 했을 때 무슨 용도인지는 이해하여야 할 것이기에, 짧게나마 소개해봤습니다.


순서

함수를 정의할 때 인수의 순서는 명확하게 정리되겠죠? 왼쪽에서부터 오른쪽까지 다음 순서입니다.

  1. 위치 인수 (기본값 X)
  2. 위치 인수 (기본값 O)
  3. / (위치 인수들 어딘가에 존재)
  4. 위치 가변 인수 (*)
  5. 키워드 전용 인수 (기본값 유무 상관 없음)
  6. 키워드 전용 가변 인수 (**)

다음은 함수를 호출할 때의 순서입니다.

  1. 키워드 없이, 차례대로
  2. 키워드 있게, 순서 상관없이

기본 값 없이 선택사항으로 만들고 싶을 때

기본 값을 특별히 만들고 싶지는 않지만 선택사항으로 두어 인수를 빼먹어도 에러가 나지 않도록 프로그램을 만들고 싶습니다. 그렇다면 None 객체를 활용합시다. 다음은 예시입니다.

def example(a, b, c=None):
    print(f'a({a})와 b({b})는 필수입니다.')
    if c is not None:
        print(f'c 값이 들어왔습니다. ==> {c}')
    else:
        print('c 값이 들어오지 않았습니다.')

example(10, 20)
example(300, 400, 500)
a(10)와 b(20)는 필수입니다.
c 값이 들어오지 않았습니다.
a(300)와 b(400)는 필수입니다.
c 값이 들어왔습니다. ==> 500

문서 읽어보기

print

우리가 밥먹듯이 쓰는 print 함수의 문서를 찾아봅시다. 정의는 다음과 같습니다.

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False):
    # 내용

첫번째로 가변 인수 objects가 등장합니다. 즉 우리가 print('안녕', '파워', '맨~', '커피')와 같이 인수를 무제한으로 넣어도 잘 작동됨을 확인할 수 있습니다. sep, end, file, flush기본값이 있는 키워드 전용 인수 임을 확인할 수 있습니다. 기본값이 있기 때문에 따로 지정해주지 않아도 알아서 잘 작동했구나 알 수 있습니다.

인수가 각각 어떤 역할을 하는지 좀 더 문서를 자세히 살펴봐야겠습니다. 여러분께서 직접 찾아보셔도 되지만, fileflush는 출력 방식과 관련된 내용이라 어려우니 패스하고 sepend가 어떤 역할인지만 살펴봅시다.

  • sep : print의 인수로 여러 개가 들어왔을 때 그것들을 구분할 문자
  • end : print가 모든 문자열의 출력을 마치고 마지막으로 출력할 문자

위에서 살펴 보았듯 sep에는 공백 하나가 기본값으로 되어 있고, end는 줄바꿈으로 되어있습니다. 직접 내용을 설정해서 호출해 볼까요?

print('안녕','하세요','반갑','습니다','하하',sep='(^o^)',end=' 뽜이야~')
print('  줄이 안바뀌었네요..?')
안녕(^o^)하세요(^o^)반갑(^o^)습니다(^o^)하하 뽜이야~  줄이 안바뀌었네요..?

어떤가요? 문서가 좀 더 잘 이해되시나요?


pandas.read_excel

pandas.read_excel(io, sheet_name=0, header=0, names=None, index_col=None, usecols=None, squeeze=False, dtype=None, engine=None, converters=None, true_values=None, false_values=None, skiprows=None, nrows=None, na_values=None, keep_default_na=True, verbose=False, parse_dates=False, date_parser=None, thousands=None, comment=None, skip_footer=0, skipfooter=0, convert_float=True, mangle_dupe_cols=True, **kwds)

어마어마하게 기네요.. io는 필수로 넣어야 할 위치 인수임을 바로 확인할 수 있고, 나머지는 선택 사항인 인수들입니다. 그 다음에는 마지막으로 kwds라는 키워드 전용 가변 인수 가 등장합니다. 설명은 따로 다시 찾아봐야 하겠지만, 함수 사용법을 일차적으로 이해하는 데 큰 의의가 있다는 것을 명심해주세요!


여담

별표는 영어로 Asterisk 라고 합니다. 아스터리스크 라고 읽는지..는 잘 모르겠습니다 호호. 별표를 영어로 검색할 일이 있을 때 참고하도록 합니다.


연습 문제

  • 함수를 정의할 때 인수의 순서가 어떻게 되는가?
  • 인수의 기본값은 어떻게 지정하는가?
  • 함수를 호출할 때 키워드를 지정하는 방법은 무엇인가?
  • 가변 인수란 무엇인가?
  • 가변 인수를 함수 내에서 이용하려면 (값을 뽑아내려면) 어떻게 해야 하는가?
  • 키워드 전용 가변 인수는 무엇인가?
  • 키워드 전용 가변 인수를 함수 내에서 이용하려면 (값을 뽑아내려면) 어떻게 해야 하는가?

프로그래밍 문제

argparse

argparse 모듈은 파이썬 스크립트를 콘솔에서 실행시킬 때 명령행 인자를 더 편리하게 관리해주는 기능을 제공합니다. 단순한 문자열의 리스트로 들어오는 데이터를 유의미한 데이터로 쉽게 변환하는 데 그 의의가 있습니다. 기본적인 사용 흐름과 예시는 다음과 같습니다.

graph TD p1["python test.py data.xlsx --temp template.html<br>를 콘솔에 입력합니다."] p1 --> p2 p2["sys.argv에 문자열을<br> 담은 리스트 형태로<Br>데이터가 생성됩니다.<br>(공백으로 리스트의<br>항목이 구분됩니다.)"] p2 -.- s1["import sys<br>print(sys.argv)"] s1 -.-> s2["['test.py', 'foo', '--bar', 'data.xlsx']"] p2 --> p3["parser.parse_args()<br>를 통해 미리 작성된<br>설정을 바탕으로 sys.argv<br>를 읽고 데이터가 담긴<br>객체를 반환합니다."] a1["import argparse<br>parser = argparse.ArgumentParser(...)<br>를 통해 ArgumentParser 객체를 생성합니다."] a2["parser.add_argument(...)<br>를 통해 불러올 데이터를<br>미리 설정합니다."] a2 --> a2 a1 --> a2 a2 --> p3

argparse 모듈을 사용하는 흐름

그리고 test.py 파일을 아래와 같이 작성합니다.

import argparse
import sys
parser = argparse.ArgumentParser()
parser.add_argument('data')
parser.add_argument('-t', '--temp')
args = parser.parse_args()
print(sys.argv)
print(args)

그리고 콘솔에서 cd 명령을 통해 작업 디렉토리를 파이썬 코드가 있는 폴더로 옮깁니다. 예제의 경우에는 바탕화면에 저장되어 있으므로 cd desktop으로 하였습니다. 그 이후 python 명령으로 작성한 파일을 실행시킵니다.

PS C:\Users\tooth> cd desktop
PS C:\Users\tooth\Desktop> python test.py data.xlsx --temp template.html
['test2.py', 'data.xlsx', '--temp', 'template.html']
Namespace(data='data.xlsx', temp='template.html')

여기서 add_argument 메서드의 설명을 잠시 끌어와보겠습니다.

ArgumentParser.add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])

  • default : 해당 옵션의 기본 값을 지정합니다.
  • help : 해당 옵션의 도움말을 지정합니다.
  • choices : 해당 옵션의 선택가능한 리스트를 지정합니다. 예를 들어 ['red', 'black']이라고 지정하면 red, black 외의 문자열은 지정할 수 없습니다.
  • required : 해당 옵션의 필수 유무를 지정합니다. 기본적으로는 False 입니다.

(후략)


문제

  1. parser.add_argument('--name', default="Peter")는 어떻게 동작하는가?

  2. parser.add_argument('-d', '--data', required=True)는 어떻게 동작하는가?

  3. parser.add_argument('type', help="색깔을 정하세요", choices=['red', 'black', 'blue']) 는 어떻게 동작하는가?

  4. 데이터 엑셀 파일과 템플릿 HTML 파일을 인수로 받고자 한다. 데이터 엑셀 파일의 기본 값은 data.xlsx, HTML 파일은 template.html로 지정하고자 하고 이 인수를 필수로 받고자 한다. 그에 따라 add_argument 메소드를 적절히 호출하라.


One thought on “파이썬 강좌 – 다양한 함수 인수 ~ 유연한 함수 만들기

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다

Scroll to top