2025년 11월 5일 수요일
오후 8:56
함수란?
함수는 입력을 받아서, 어떤 일을 수행하고, 결과를 돌려주는 것
특정 하나의 기능을 수행하는 명령들의 모임
라면 끓이기라면 더 세분화 해서 가스레인지 올리기, 불켜기, 물붓기, 스프넣기…
하나의 기능을 하는것이고 여러 개 순차적인 명령을 모은 기능
❖반복되는 작업을 줄이고 재사용성 증가
❖ 코드를 잘게 나눠서 정리
❖ 유지보수와 수정 그리고 가독성을 위함
크게 내장 함수, 사용자 정의 함수가 있다.
내장 함수 - 기본적으로 탑재가 되어있으므로 사용만 하면
사용자 정의 함수 - 사용자가 직접 함수를 정의하는 방식
대표적으로 지금까지 본 함수들
len(), input(), type(), print()
다양한 내장 함수
Max - 시퀀스 자료의 최댓값 출력
Min - 시퀀스 자료의 최솟값 출력
Sum - 시퀀스 자료의 합을 출력
사용자 정의 함수 - 사용자가 여러 명령들을 묶어 직접 정의한 함수
Def 키워드, 함수이름, 매개변수, :, body, call
함수를 실행하려면 함수를 호출해야 한다(call)
Def 키워드 - 함수 정의하겠다.
함수 이름 - 함수를 구분
• 함수는 어떠한 동작(Action)이므로 동사 형태
• snake_case를 활용
(1)매개변수 - 대응되는 변수를 의미, ()안에 정의, 입력한 값을 받는 변수
(2)인자 - 함수에 전달하는 값 10이 인자가 되고 매개변수 x에 대응된다.
(3)Body - 실질적인 명령 작성, 들여쓰기를 통해 명령들을 종속
(4)함수의 반환 - 영어로 리턴이라 표현, 최종 결과값을 반환, 함수를 호출한 쪽으로 전달
(5)함수 호출 - 호출해야 함수 내부 코드가 동작한다. 매개변수에 대응되는 인자를 반드시 넘겨야 전달 받아서 동작
def add(num1, num2):
return num1 + num2
def sub(num1, num2):
return num1 - num2
def mul(num1, num2):
return num1 * num2
def div(num1, num2):
return num1 / num2
print(add(3, 5))
print(sub(10, 7))
print(mul(4, 6))
print(div(15, 5))
8
3
24
3.0
들여쓰기 된 부분 내부
그외의 부분 외부다.
def formula(a, b):
c = (a**2) + (b**2)
print("return: ", c)# 첫번째 출력
formula(2, 4) # 두번째 출력
result = formula(2,4)
print("result: ", result)# 세번째 출력
return: 20
return: 20
result: None
함수 내부에 일어난 일은 외부에서 모르기에 반환을 통해서 전달
반환 값이 어딘가에 활용되어야 하면 리턴쓴다.
디폴트 매개변수
컨트리라고 하는 값의 디폴트다.
함수호출시 매개변수 없으면 그냥 컨트리가 Korea가 된다.
디폴트 매개변수의 반대는 리콰이어드 매개변수고 디폴트 매개변수는 항상 마지막에
정의
가변 매개변수 - 여러 개의 값을 한번에 받을 수 있는 매개변수
*args
• 매개변수 이름 앞에 *을 붙여주면 가변 매개변수가 된다.
• 전달 받은 매개변수는 Tuple 형태로 받은 값들을 묶는다.
3개를 넣든 4개를 넣든 상관없음, 개수의 제한이 없다고 함.
여기선 3개를 넣음
유연하게 매개변수 값을 받고 싶을 때 사용한다.
함수 매개변수의 확장: 매개변수 이름으로 인자 전달
주의할 점!: 키워드 인자가 나오면, 그 뒤의 모든 인자는 반드시 키워드 형태여야 함
def sum_score(kor, eng, math):
return kor+eng+math
print(sum_score(70, eng=80, 90))
Cell In[41], line 4
print(sum_score(70, eng=80, 90))
^
SyntaxError: positional argument follows keyword argument
매개변수 이름으로 인자를 넣어야 한다.
print(sum_score(70,80,90))
이렇게 값만 불러와도 됨
이름 없어야 한다. 맨 앞에
print(sum_score(kor = 70,80,90))
이름 있어야 한다. 맨 뒤에
print(sum_score(70,80,math = 90))
디폴트가 없는건(매개변수는) 앞에 디폴트가 있는건 뒤에
함수와 언패킹/패킹 활용
함수의 인자로 리스트(또는 투플)에 *을 붙여주면 Unpacking을 수행.
일대일 매치가 되어야 함 마이리스트를 언패킹 해줌으로써 세개로 분리가 된다.
함수의 반환 부분에 여러 개의 값을 반환할 수 있다.
def three(x, y):
return x, x**2, x**3, x**4, x*y
a, b, c, d, e = three(4,3)
print(a, e, b, d, c)
print(min(a, b, c, d, e))
print(max(a, b, c, d, e))
print(sorted(three(4,3)))
print(len(three(4,3)))
4 12 16 256 64
4
256
[4, 12, 16, 64, 256]
5
[4, 12, 16, 64, 256]
이런식으로 내부함수도 사용가능
지역변수와 전역변수
함수 내부에서 일어난 일은 함수 밖에 영향을 끼치지 않는다
함수안에 일어난 모든 것들은 함수밖에 영향을 끼칠수 없다.
지역 변수 - 해당 지역 내에서 활용가능한 변수
전역 변수 - 전역적인 범위에서 사용 가능한 변수
Global_var은 전역 변수라서 어디서든 쓸수 있다.
한마디로 local_var은 지역 변수 라서
함수 밖에선 쓸수 없다.
변수에 실제 값이 저장되어있는 것이 아니라, 값이 보관된 메모리 주소의 값을 저장하고 있다. 그리고 해당 객체를 참조(Reference)하고 있는 구조이다.
전역변수
전역 변수는 Global Namespace 영역에 {이름: 객체} 딕셔너리 형태로 저장되어 있음 Stack 영역에 Global Namespace에 대한 포인터(참조)가 있어서 함수 내부에서 전역 변수 참조
수정하려면 변수앞에 Global 키워드 붙이기
객체지향 프로그래밍
객체를 중심으로 프로그래밍하는 패러다임 객체지향 프로그래밍에서는 모든 것을 객체(Object)로 간주한다.
사람이라 하면 키 몸무게 나이 등 하나로 묶어서 정의 하기 위해 등장했다.
모니터 마우스 키보드 등 모든 (주변사물)것이 객체
클래스란?
눈코입귀 같은것들이 사람들의 공통적 속성이다.
이름, 나이 등 사람의 공통적 속성을 가져온다.
여러 속성을 하나로 묶기 위해 필요한게 클래스
코딩관점의 클래스란?
클래스는 속성(Attribute), 동작(Behavior)을 갖고 있는 일종의 자료형이다
설계도와 같은 역할 객체는 설계도를 바탕으로 만들어진 실제 객체다.
실제 메모리상에 생성된 객체 = 인스턴스
클래스 예시1: 붕어빵 클래스
붕어빵
속성:
속 재료, 양
동작:
속 채우기, 붕어빵 꺼내기, 속 양 조절하기
클래스 예시2: 자동차 클래스
속성: 색상, 연비, 모델명
동작: 시동 걸기, 가속하기, 멈추기, 기어 변경
클래스 정의 및 객체 생성하기
클래스 이름, 클래스의 속성(변수), 클래스의 동작(메서드), 객체 생성
클래스(Class) 정의하기: 클래스 이름
퍼스칼 케이스 활용-> 단어 첫글자가 대문자 Car, SmartPhone, Dog, Student
생성자 - 객체를 생성할때 만들어지는 함수
init 라고 함
객체를 생성될 때 호출되는 함수
호출할때 클래스 이름으로 호출한다.
인스턴스 생성 시, 단 한 번 호출
클래스의 속성 정의하고, 초기화하는 작업에 사용
name과 age 속성 변수를 생성 후, 생성자의 매개변수로 받은 값으로 초기화
Self.name, self.age은 직관적으로 속성을 만드는 것.
35값을 받아와서 초기화 시키겠다.
인스턴스 변수 - 클래스 속성으로 정의 된 변수
클래스 안에 정의된 변수를 인스턴스 라 함
셀프 키워드가 뭐냐? 객체 자기자신을 의미, self 키워드는 맨앞에 있어야 함
실제 객체가 생성되었을 때, self가 해당 객체 자기자신이 되는 것 이름이 John이며 나이가 36인 사람
한 마디로 중심 객체gildong에 이름Gildong, 나이22가 대입되고
John이라는 중심객체에 이름 John, 나이40가 대입된다.
그런뜻
제미나이 설명: "현재 만들어지고 있는 이 객체(this)의 속성(name)에, // 입력값으로 들어온 이름(name)을 넣어라."
인스턴스 메서드
클래스 내부에 정의된 함수
호출시 객체.메서드()형태로 호출
누가 뭐뭐가 한다
함수는 주체가 없다.
함수는 독립적 호출
메서드는 주체가 있다.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def walk(self):
print(f"{self.name}이 {self.age}살이며, 걷습니다.")
def eat(self, food):
print(f"{self.name}이{self.age}살이고, {food}를 먹습니다.")
gildong = Person("Gildong", 22)
john = Person("John", 40)
gildong.walk()
john.eat("Banana")
Gildong이 22살이며, 걷습니다.
John이40살이고, Banana를 먹습니다.
Exercise
class Car:
def __init__(self, name, speed):
self.name = name
self.speed = speed
def get_name(self):
return self.name
def get_speed(self):
return self.speed
audi = Car("Audi", 10)
bmw = Car("BMW", 30)
print(f"{audi.get_name()}'s speed is {audi.get_speed()}")
print(f"{bmw.get_name()}'s speed is {bmw.get_speed()}")# 캡슐화 라고 한다.
함수 형태로 정의 self.name, self.speed를 반환
그 다음에 각각 이름과, 속도가 있는 객체 생성
각각 이름과 속도를 출력하기 위해
각각 네임과 스피드가 반환이 됨
속성값을 그대로 노출하면 바뀔수 있는 위험이 있음
속성값을 안전하게 다루는것이 캡슐화
그것을 다루는 것이 게터 세터라고 함 (이부분 다시 들어보는거 추천 this부터)
8번
문제 설명
비밀번호가 유효한지 검사하는 함수 validate_password를 작성하세요. 비밀번호는 다음 조건을 모두 만족해야 합니다:
함수는 유효성 여부(True/False)와 실패 이유를 모두 반환(투플 형태)해야 합니다. 5개의 비밀번호를 검사하고 각각 결과를 출력하세요.
입력 예시:
# 호출 예시
passwords = ["abc123", "password", "Pass1234", "12345678", "MyP@ss99"]
for pwd in passwords:
is_valid, message = validate_password(pwd)
출력 예시:
비밀번호: abc123
결과: 실패 (길이가 8자 미만입니다)
비밀번호: password
결과: 실패 (숫자가 포함되지 않았습니다)
비밀번호: Pass1234
결과: 성공
비밀번호: 12345678
결과: 실패 (영문자가 포함되지 않았습니다)
비밀번호: MyP@ss99
결과: 성공
내가 한 풀이
password = ["abc123", "password", "Pass1234", "12345678", "MyP@ss99"]
def valid_password(pwd):
if len(pwd) < 8:
is_valid = "실패"
message = "(길이가 8자 미만입니다.)"
# tp = is_valid, message
elif str.isalpha(pwd) == True:
is_valid = "실패"
message = "(숫자가 포함되지 않았습니다.)"
# tp = is_valid, message
elif str.isdigit(pwd) == True:
is_valid = "실패"
message = "(영문자가 포함되지 않았습니다.)"
# tp = is_valid, message
else:
is_valid = "성공"
message = ""
return is_valid, message
for pwd in password:
is_valid, message = valid_password(pwd)
print(f"비밀번호: {pwd}")
print(f"결과: {is_valid} {message}")
피드백
나는 isalpha, isdigit 함수를 썼다.
If문 안에 그냥 return 실패, 실패사유 이렇게 리턴하는 방법도 좋음
For문안에 isdigit 메서드 안쓰는 대신,
"1"<= ch <="9" 조건문도 쓰기.
마찬가지로 isalpha 메서드 대신 조건문"a"<=ch <="z" or "A"<=ch<="Z"
변수도 has_digit, has_alpha 를 만들어서 조건문에 일치안하면
False, "에러메시지" 반환시키는 것
다 조건문에 안 걸려들면 return True, "성공"
9번
문제 설명
문자열을 다양한 방식으로 변환하는 함수들을 구현하세요.
join_with_space(words): 단어 리스트에서 각 단어를 공백으로 연결하여 하나의 문자열로 반환count_chars(text, *chars): 텍스트에서 매개 변수로 받은 여러 문자의 각 출현 횟수를 딕셔너리로 반환 (가변 인자 사용)입력 예시:
# 호출 예시
word_list = ["Python", "is", "fun"]
result = join_with_space(word_list)
text = "hello world programming"
print("문자 개수: ", count_chars(text, 'o', 'l', 'r'))
출력 예시:
결합된 문장: Python is fun
문자 개수: {'o': 3, 'l': 3, 'r': 2}
내가 한 풀이
word_list = ["Python", "is", "fun"]
def join_with_space(word_list):
result = " ".join(word_list)# join 함수 안쓰고 시도 해보기
return result
text="hello world programming"
tp = ("o", "l", "r")
dic = {}
def count_chars(text, *chars):#함수 안에 반복문 써도 되긴 하고 두개 써보기 o, l, r각각 갯수세기
for i in range(len(chars)):
dic[tp[i]] = text.count(tp[i])# 여기에 int가 들어감
# result = {} # 결과 변수
# 코드를 구현하세요.
return dic
# 위 정의한 함수들 호출하여 결과를 출력하세요.
print(f"결합된 문장: {join_with_space(word_list)}")
print(f"문자개수: {count_chars(text, *tp)}")# tp 언패킹 하거나 tp 변수를 없애거나 둘중 하나의 방식
이것도 join 함수를 안쓴다면?
이것도 반복문을 돌려서 result에 추가를 한다면
마지막만 공백이 안들어가게 끔 해야 한다.
이럴려면 조건문을 넣어서 현재 인덱스 변수, 순번이 word_list보다 작은 경우
공백 넣기
아닐 경우 더해지지 않는다.
If i < len(word_list) - 1:
result += " "
여기서도 .count 메서드를 안쓰고 count 변수로 세보는 방법
For char in chars:
count = 0
for t in text:
if char == t:
count += 1
result[char] = count
return result
언패킹 안하고 그냥 튜플을 변수로 넣는 방법도 있다.