- 프롤로그
- 개발 첫걸음
- 파이썬 기초
- 파이썬 중급
- 파이썬 고급
- 내장 함수 톺아보기
- 예외와 에러 – 예상치 못한 상황에 대응하기 (v0.1)
- 변수의 범위 – 이름 검색의 범위
- 파이썬 심화
- 시퀀스와 반복자 – 반복과 순회를 자유자재로 다루기
- 데코레이터 – 함수의 기능을 강화하기
- 프로퍼티
- 제너레이터
- async와 await
- 객체로서의 클래스 – 클래스를 동적으로 정의하기
- 파이썬 프로젝트 실습
- 원카드 게임 만들기 (1)
- 원카드 게임 만들기 (2)
- 원카드 게임 만들기 (3) (작성중)
- 턴제 자동 전투 게임 만들기 (작성중)
- 실전 (파이썬 외적인 것들)
- 정규표현식 – 문자열을 검색하고 치환하기 (작성중)
- 유니코드 – 컴퓨터에서 문자를 표기하는 방법
- html, css, 인터넷 – 자동화 첫 걸음 내딛기
- 네트워크 – 인터넷으로 통신하는 방법
- 문서 – 문맥을 읽어보기
기본값(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
또한 매번 인수로 값을 받을 수 밖에 상황이기에 a
의 default
는 사실상 필요가 없어집니다. 이러한 설계상의 결함을 최소화하기 위해 아예 에러로 처리하는 파이썬 인터프리터의 모습을 확인할 수 있습니다. (추가 예정)
가변 인수 (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는 위치 기반으로 접근할 수 없습니다.
위치 전용 인수는 일반 사용자보다는 라이브러리 설계자가 이용하도록 고안된 것이며 우리가 함수를 정의할 때 이를 사용하는 일은 드물 것입니다. 하지만 파이썬 표준에 포함된 만큼 어떤 라이브러리가 /
를 사용한다고 했을 때 무슨 용도인지는 이해하여야 할 것이기에, 짧게나마 소개해봤습니다.
순서
함수를 정의할 때 인수의 순서는 명확하게 정리되겠죠? 왼쪽에서부터 오른쪽까지 다음 순서입니다.
- 위치 인수 (기본값 X)
- 위치 인수 (기본값 O)
/
(위치 인수들 어딘가에 존재)- 위치 가변 인수 (
*
) - 키워드 전용 인수 (기본값 유무 상관 없음)
- 키워드 전용 가변 인수 (
**
)
다음은 함수를 호출할 때의 순서입니다.
- 키워드 없이, 차례대로
- 키워드 있게, 순서 상관없이
팁
기본 값 없이 선택사항으로 만들고 싶을 때
기본 값을 특별히 만들고 싶지는 않지만 선택사항으로 두어 인수를 빼먹어도 에러가 나지 않도록 프로그램을 만들고 싶습니다. 그렇다면 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(*objects, sep=' ', end='\n', file=sys.stdout, flush=False):
# 내용
첫번째로 가변 인수 objects
가 등장합니다. 즉 우리가 print('안녕', '파워', '맨~', '커피')
와 같이 인수를 무제한으로 넣어도 잘 작동됨을 확인할 수 있습니다. sep
, end
, file
, flush
는 기본값이 있는 키워드 전용 인수 임을 확인할 수 있습니다. 기본값이 있기 때문에 따로 지정해주지 않아도 알아서 잘 작동했구나 알 수 있습니다.
인수가 각각 어떤 역할을 하는지 좀 더 문서를 자세히 살펴봐야겠습니다. 여러분께서 직접 찾아보셔도 되지만, file
과 flush
는 출력 방식과 관련된 내용이라 어려우니 패스하고 sep
와 end
가 어떤 역할인지만 살펴봅시다.
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
모듈은 파이썬 스크립트를 콘솔에서 실행시킬 때 명령행 인자를 더 편리하게 관리해주는 기능을 제공합니다. 단순한 문자열의 리스트로 들어오는 데이터를 유의미한 데이터로 쉽게 변환하는 데 그 의의가 있습니다. 기본적인 사용 흐름과 예시는 다음과 같습니다.
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
입니다.
(후략)
문제
-
parser.add_argument('--name', default="Peter")
는 어떻게 동작하는가? -
parser.add_argument('-d', '--data', required=True)
는 어떻게 동작하는가? -
parser.add_argument('type', help="색깔을 정하세요", choices=['red', 'black', 'blue'])
는 어떻게 동작하는가? -
데이터 엑셀 파일과 템플릿 HTML 파일을 인수로 받고자 한다. 데이터 엑셀 파일의 기본 값은
data.xlsx
, HTML 파일은template.html
로 지정하고자 하고 이 인수를 필수로 받고자 한다. 그에 따라add_argument
메소드를 적절히 호출하라.
- 프롤로그
- 개발 첫걸음
- 파이썬 기초
- 파이썬 중급
- 파이썬 고급
- 내장 함수 톺아보기
- 예외와 에러 – 예상치 못한 상황에 대응하기 (v0.1)
- 변수의 범위 – 이름 검색의 범위
- 파이썬 심화
- 시퀀스와 반복자 – 반복과 순회를 자유자재로 다루기
- 데코레이터 – 함수의 기능을 강화하기
- 프로퍼티
- 제너레이터
- async와 await
- 객체로서의 클래스 – 클래스를 동적으로 정의하기
- 파이썬 프로젝트 실습
- 원카드 게임 만들기 (1)
- 원카드 게임 만들기 (2)
- 원카드 게임 만들기 (3) (작성중)
- 턴제 자동 전투 게임 만들기 (작성중)
- 실전 (파이썬 외적인 것들)
- 정규표현식 – 문자열을 검색하고 치환하기 (작성중)
- 유니코드 – 컴퓨터에서 문자를 표기하는 방법
- html, css, 인터넷 – 자동화 첫 걸음 내딛기
- 네트워크 – 인터넷으로 통신하는 방법
- 문서 – 문맥을 읽어보기
4 thoughts on “파이썬 강좌 – 다양한 함수 인수 ~ 유연한 함수 만들기”