기타 제어 흐름 도구
if
if x < 0:
x = 0
print('Negative changed to zero')
elif x == 0:
print('Zero')
elif x == 1:
print('Single')
else:
print('More')
for
- 루프의 else 절은 break가 발생하지 않을 때 실행
결과for n in range(2, 10): for x in range(2, n): if n % x == 0: print(n, 'equals', x, '*', n//x) break else: # loop fell through without finding a factor print(n, 'is a prime number')
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3
pass 문
- pass 문은 아무것도 하지 않습니다. 문법적으로 문장이 필요하지만, 프로그램이 특별히 할 일이 없을 때 사용할 수 있습니다.
while True: pass # Busy-wait for keyboard interrupt (Ctrl+C)
class MyEmptyClass:
pass
### match Statements
```python
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def where_is(point):
match point:
case Point(x=0, y=0):
print("Origin")
case Point(x=0, y=y):
print(f"Y={y}")
case Point(x=x, y=0):
print(f"X={x}")
case Point():
print("Somewhere else")
case _:
print("Not a point")
# "Origin"
where_is(Point(0, 10))
match_args
match_args의 목적:
- 이 속성은 클래스의 인스턴스를 패턴 매칭할 때 위치 기반 인자를 사용할 수 있게 해줍니다.
- 클래스의 어떤 속성들을 패턴 매칭에 사용할지 정의합니다.
작동 방식:
- match_args는 튜플로 정의되며, 클래스 속성의 이름을 순서대로 포함합니다.
- 이 순서는 패턴 매칭에서 인자의 순서와 일치합니다.
class Point:
__match_args__ = ('x', 'y')
def __init__(self, x, y):
self.x = x
self.y = y
# 이제 다음과 같은 패턴 매칭이 가능합니다:
point = Point(0, 5)
match point:
case Point(0, y):
print(f"Point on Y-axis at y={y}")
가드 조건
- if를 사용하여 추가 조건을 지정할 수 있습니다.
case Point(x, y) if x == y: print(f"Y=X at {x}")
시퀀스 패턴:
리스트나 튜플 같은 시퀀스도 매칭
match points:
case []:
print("No points")
case [Point(0, 0)]:
print("The origin")
case [Point(x, y)]:
print(f"Single point {x}, {y}")
as
기본 개념:
as 키워드는 패턴 매칭에서 전체 패턴이나 서브패턴을 변수에 바인딩할 때 사용됩니다.
이를 통해 매칭된 전체 값을 유지하면서 동시에 그 내부의 특정 부분을 추출할 수 있습니다.
class Point:
__match_args__ = ('x', 'y')
def __init__(self, x, y):
self.x = x
self.y = y
def analyze_points(points):
match points:
case (Point(x1, y1), Point(x2, y2) as p2):
print(f"First point: ({x1}, {y1})")
print(f"Second point: ({x2}, {y2})")
print(f"Full second point object: {p2}")
# 사용 예
point1 = Point(1, 2)
point2 = Point(3, 4)
analyze_points((point1, point2))
- (Point(x1, y1), Point(x2, y2) as p2) 패턴은 두 개의 Point 객체로 구성된 튜플을 매칭합니다.
- 첫 번째 Point의 x와 y 값은 x1과 y1에 바인딩됩니다.
- 두 번째 Point의 x와 y 값은 x2와 y2에 바인딩됩니다.
- 동시에, 두 번째 Point 객체 전체가 p2라는 변수에 바인딩됩니다.
as의 장점:
전체 구조를 유지하면서 세부 정보에 접근할 수 있습니다.
복잡한 객체나 구조에서 특정 부분만 추출하고 싶을 때 유용합니다.
매칭된 전체 객체를 참조해야 할 때 편리합니다.
def process_data(data):
match data:
case {"user": {"name": name, "age": age} as user_info}:
print(f"Name: {name}, Age: {age}")
print(f"Full user info: {user_info}")
case [*items] as full_list if len(items) > 5:
print(f"Long list with {len(items)} items")
print(f"Full list: {full_list}")
- 첫 번째 케이스는 중첩된 딕셔너리에서 특정 필드를 추출하면서 전체 사용자 정보도 유지합니다.
- 두 번째 케이스는 리스트의 모든 항목을 items에 언패킹하면서 전체 리스트도 full_list로 캡처합니다.
'언패킹'과 '캡처'
언패킹(Unpacking):
언패킹은 시퀀스(리스트, 튜플 등)나 이터러블(iterable) 객체의 요소들을 개별 변수로 분리하는 과정
numbers = [1, 2, 3]
a, b, c = numbers # 이것이 언패킹입니다.
print(a) # 1
print(b) # 2
print(c) # 3
*를 사용한 언패킹:
*는 "나머지 모든 항목"을 의미합니다. 리스트의 모든 항목을 하나의 변수에 담을 때 사용
numbers = [1, 2, 3, 4, 5]
first, *rest = numbers
print(first) # 1
print(rest) # [2, 3, 4, 5]
실전 예시
def process_list(data):
match data:
case [*items] as full_list if len(items) > 3:
print(f"Items: {items}")
print(f"Full list: {full_list}")
print(f"First item: {items[0]}")
print(f"List length: {len(full_list)}")
# 사용 예
my_list = [10, 20, 30, 40, 50]
process_list(my_list)
# 출력
Items: [10, 20, 30, 40, 50]
Full list: [10, 20, 30, 40, 50]
First item: 10
List length: 5
- items는 리스트의 모든 항목을 포함하는 새 리스트입니다 (언패킹 결과).
- full_list는 원본 리스트 전체를 그대로 참조합니다.
- 둘 다 같은 내용을 가지지만, items는 새로운 리스트 객체이고 full_list는 원본 리스트를 가리킵니다.
함수
함수의 기본 개념:
함수는 특정 작업을 수행하는 코드 블록입니다. 코드를 재사용 가능하게 만들고, 프로그램을 더 구조화하고 관리하기 쉽게 만듭니다.
함수 정의 방법:
def 함수이름(매개변수1, 매개변수2, ...):
"""독스트링(선택사항)"""
# 함수 내용
return 결과값(선택사항)
def: 함수 정의를 시작하는 키워드입니다.
함수이름: 함수를 호출할 때 사용할 이름입니다.
매개변수: 함수에 전달할 값들입니다. 필요 없으면 비워둘 수 있습니다.
독스트링: 함수의 설명을 작성합니다. 선택사항이지만, 작성을 권장합니다.
return: 함수의 결과값을 반환합니다. 없으면 자동으로 None을 반환합니다.
반환값:
return을 사용해 함수의 결과를 반환할 수 있습니다.
return이 없으면 함수는 None을 반환합니다.
기본 인자 값
def ask_ok(prompt, retries=4, reminder='Please try again!'):
while True:
reply = input(prompt)
if reply in {'y', 'ye', 'yes'}:
return True
if reply in {'n', 'no', 'nop', 'nope'}:
return False
retries = retries - 1
if retries < 0:
raise ValueError('invalid user response')
print(reminder)
키워드 인자
키워드 인자 기본 개념:
- 함수 호출 시 kwarg=value 형식으로 사용합니다.
- 인자의 이름을 명시적으로 지정하여 값을 전달합니다.
함수 정의 예시
def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
# 함수 내용
- voltage는 필수 인자
- state, action, type은 기본값이 있는 선택적 인자
함수 호출 방법:
- 위치 인자만 사용: parrot(1000)
- 키워드 인자만 사용: parrot(voltage=1000)
- 위치 인자와 키워드 인자 혼용: parrot('a thousand', state='pushing up the daisies')
키워드 인자 사용 규칙:
- 키워드 인자는 위치 인자 뒤에 와야 합니다.
- 모든 키워드 인자는 함수 정의의 매개변수와 일치해야 합니다.
- 동일한 인자에 중복 값을 제공할 수 없습니다.
가변 인자 (args와 *kwargs):
*args
: 추가적인 위치 인자를 튜플로 받습니다.**kwargs
: 추가적인 키워드 인자를 딕셔너리로 받습니다.
def cheeseshop(kind, *arguments, **keywords):
print("-- Do you have any", kind, "?")
print("-- I'm sorry, we're all out of", kind)
for arg in arguments:
print(arg)
print("-" * 40)
for kw in keywords:
print(kw, ":", keywords[kw])
cheeseshop("Limburger", "It's very runny, sir.",
"It's really very, VERY runny, sir.",
shopkeeper="Michael Palin",
client="John Cleese",
sketch="Cheese Shop Sketch")
-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
shopkeeper : Michael Palin
client : John Cleese
sketch : Cheese Shop Sketch
특수 매개변수
특수 매개변수의 종류:
- a) 위치 전용 매개변수 (Positional-only)
-b) 위치-키워드 매개변수 (Positional-or-Keyword) - c) 키워드 전용 매개변수 (Keyword-only)
def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
pass
/
앞: 위치 전용/
와*
사이: 위치-키워드*
뒤: 키워드 전용
위치 전용 매개변수 (/ 앞):
반드시 위치에 따라 인자를 전달해야 함
키워드로 전달할 수 없음
위치-키워드 매개변수 (/와 * 사이):
위치 또는 키워드로 인자 전달 가능
키워드 전용 매개변수 (* 뒤):
반드시 키워드로 인자를 전달해야 함
def standard_arg(arg):
print(arg)
def pos_only_arg(arg, /):
print(arg)
def kwd_only_arg(*, arg):
print(arg)
def combined_example(pos_only, /, standard, *, kwd_only):
print(pos_only, standard, kwd_only)
standard_arg(2)
standard_arg(arg=2)
# 두 번째 함수 pos_only_arg는 함수 정의에 /가 있으므로 위치 매개 변수만 사용하도록 제한
pos_only_arg(1)
# 세 번째 함수 kwd_only_args는 함수 정의에서 *로 표시된 키워드 인자만 허용
kwd_only_arg(arg=3)
# 마지막은 같은 함수 정의에서 세 가지 호출 규칙을 모두 사용
combined_example(1, standard=2, kwd_only=3)
기타
인자 목록 언패킹:
*
: 리스트나 튜플을 위치 인자로 풀어줍니다.**
: 딕셔너리를 키워드 인자로 풀어줍니다.
args = [3, 6]
list(range(*args)) # [3, 4, 5]
d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
parrot(**d)
람다 표현식:
작고 이름 없는 함수를 만듭니다.
문법: lambda 인자: 표현식
예:
add = lambda a, b: a + b
make_incrementor = lambda n: lambda x: x + n
a = make_incrementor(10)
print(a(10)) # 20
도큐멘테이션 문자열 (독스트링):
함수의 목적과 사용법을 설명합니다.
첫 줄은 간결한 요약, 두 번째 줄은 비움, 그 후로 상세 설명.
예:
def my_function():
"""Do nothing, but document it.
No, really, it doesn't do anything.
"""
pass
함수 어노테이션:
함수 매개변수와 반환값의 타입을 명시합니다.
문법: def 함수명(매개변수: 타입, ...) -> 반환타입:
예:
def f(ham: str, eggs: str = 'eggs') -> str:
return ham + ' and ' + eggs
출처: 파이썬 자습서