Fullstack 62

heo4·2026년 7월 13일

Fullstack

목록 보기
17/70

풀스택

Python 함수(Function) 정리

국비과정에서 배운 파이썬 함수를 정리했다. 기본 정의부터 매개변수/반환값, 콜백 함수, 람다, 그리고 파일 입출력까지 한 번에 다룬다.

1. 함수란?

함수는 특정 작업을 묶어 이름을 붙여둔 코드 블록이다.

  • def 키워드로 정의한다.
  • 함수를 쓰면 재사용성 · 가독성 · 유지보수성이 좋아진다.

예제 1) 간단한 함수 정의와 호출

def greet():
    print("안녕하세요!")
    print("파이썬 함수에 오신 것을 환영합니다.")
    print("이 함수는 단순히 인사를 합니다.")

greet()
greet()
print("함수 호출 완료!")

예제 2) 매개변수와 return의 유무에 따른 함수

# 매개변수, return 모두 없는 함수
def printHello():
    print("Hello World")

printHello()

# 매개변수는 있고, return이 없는 함수
def printName(name):
    print("Hello " + name)

printName("김수한")

함수는 매개변수(입력)와 return(출력)의 유무에 따라 4가지 조합(둘 다 없음 / 매개변수만 / return만 / 둘 다 있음)으로 나뉜다.


2. 매개변수와 return

함수는 입력값(매개변수)을 받을 수 있고, return으로 결과값을 호출한 곳에 돌려줄 수 있다.

예제 1) 매개변수와 반환값

def add(a, b):
    result = a + b
    return result

x = add(3, 5)
print("3 + 5 =", x)

y = add(10, 20)
print("10 + 20 =", y)

예제 2) 여러 개 반환

파이썬 함수는 값을 콤마로 구분해서 여러 개 반환할 수 있다. 이때 내부적으로는 튜플이 반환되는 것이다.

def min_max(nums):
    return min(nums), max(nums)

numbers = [4, 7, 1, 9, 3]
low, high = min_max(numbers)  # low=1, high=9

print("리스트:", numbers)
print("최솟값:", low)
print("최댓값:", high)

3. 콜백 함수

함수의 인자로 다른 함수 자체를 전달할 수 있다. 이렇게 인자로 넘겨지는 함수를 콜백 함수(Callback Function)라고 부른다.

예제 1) 함수를 인자로 전달

def calc(a, b, func):
    return func(a, b)

def add(x, y):
    return x + y

def mul(x, y):
    return x * y

print("덧셈:", calc(3, 4, add))
print("곱셈:", calc(3, 4, mul))

calc 함수는 어떤 연산을 할지 스스로 정하지 않고, 인자로 받은 func에게 위임한다. 덕분에 calc를 수정하지 않고도 다양한 연산을 끼워 넣을 수 있다.

예제 2) 콜백 응용

def greet(name, formatter):
    return formatter(name)

def simple_format(n):
    return f"안녕하세요, {n}!"

def excited_format(n):
    return f"반가워요, {n}!!!"

print(greet("Alice", simple_format))
print(greet("Bob", excited_format))

4. 람다 함수

lambda는 이름 없이 즉석에서 만드는 한 줄짜리 익명 함수다. 간단한 동작을 빠르게 정의할 때 쓴다.

예제 1) 기본 람다

square = lambda x: x * x

print("3 제곱:", square(3))
print("7 제곱:", square(7))

lambda 매개변수: 반환값 형태로, def+return 조합을 한 줄로 축약한 것이라고 보면 된다.

예제 2) 정렬에 활용

람다는 sort()나 sorted()의 key 인자로 자주 쓰인다.

students = [("Lee", 40), ("hancoding", 25), ("Kim Suhan", 19)]

# 나이(두 번째 요소) 기준 정렬
students.sort(key=lambda s: s[1])
print("나이순 정렬:", students)

# 이름 길이 기준 정렬
students.sort(key=lambda s: len(s[0]))
print("이름 길이순 정렬:", students)

5. 파일 입출력

open("파일명", "모드")로 파일을 열고 read()/write()로 내용을 다룬다.

모드설명
"r"읽기
"w"쓰기 (기존 내용 덮어씀)
"a"추가 (기존 내용 뒤에 이어씀)

예제 1) 파일 쓰기

f = open("test.txt", "w", encoding="utf-8")
f.write("Hello, Python!\n")
f.flush()
f.write("파일 입출력 연습입니다.\n")
f.close()
print("파일 쓰기 완료")

💡 open()으로 연 파일은 반드시 close()로 닫아줘야 한다. (실무에서는 with open(...) as f: 구문으로 자동으로 닫는 방식을 더 많이 쓴다.)

예제 2) 파일 읽기

f = open("test.txt", "r", encoding="utf-8")
lines = f.readlines()
f.close()

for line in lines:
    print("읽은 줄:", line.strip())

readlines()는 파일의 각 줄을 리스트로 반환한다. 줄 끝의 개행문자(\n)는 strip()으로 제거하는 게 일반적이다.


6. 연습문제

문제 1

두 수를 매개변수로 받아 합과 곱을 동시에 반환하는 함수를 정의하고 실행하기.

정답 코드 보기
def calc(a, b):
    return a + b, a * b

x = int(input("첫 번째 정수:"))
y = int(input("두 번째 정수:"))

result1, result2 = calc(x, y)

print(f"합: {result1}, 곱:{result2}")

문제 2

학생 이름과 점수를 입력받아 딕셔너리로 저장하고, 등록/목록/종료 메뉴를 함수로 구현하기.

정답 코드 보기
dict = {}  # 딕셔너리

def inputCommand():
    print("1. 학생 등록")
    print("2. 학생 목록")
    print("0. 프로그램 종료")
    cmd = int(input("명령어 입력:"))
    return cmd

def printStudent(dict):
    for name, score in dict.items():
        print(f"학생 이름: {name} / 학생 점수: {score}")

def insertStudent(dict):
    name = input("학생 이름:")
    score = int(input("학생 점수:"))
    dict[name] = score

while True:
    cmd = inputCommand()

    if cmd == 1:
        insertStudent(dict)
    elif cmd == 2:
        printStudent(dict)
    elif cmd == 0:
        print("프로그램 종료")
        break
    else:
        print("존재하지 않는 명령어입니다.")

문제 3

students.txt 파일에 아래 세 줄을 저장하는 프로그램 작성하기.

홍길동, 90
김철수, 85
이영희, 95
정답 코드 보기
f = open("students.txt", "w", encoding="utf-8")
f.write("홍길동, 90\n")
f.write("김철수, 85\n")
f.write("이영희, 95")
f.close()

문제 4

문제 3에서 작성한 students.txt를 읽어서 한 줄씩 화면에 출력하기.

정답 코드 보기
f = open("students.txt", "r", encoding="utf-8")
lines = f.readlines()
f.close()

for line in lines:
    print(line.strip())

문제 5

students.txt 파일을 읽어 점수의 총합과 평균을 구하기.

출력 예시

총점: 270
평균: 90.0
정답 코드 보기
f = open("students.txt", "r", encoding="utf-8")
lines = f.readlines()
f.close()

total = 0
count = 0

for line in lines:
    lst = line.split(",")
    name = lst[0]
    score = int(lst[1].strip())
    total += score
    count += 1

print("점수의 총합:", total)
print(f"점수의 평균: {total / float(count):.2f}")

마무리

  • 함수는 매개변수/반환값 유무 조합을 먼저 구분해서 이해하면 헷갈리지 않는다.
  • 콜백 함수는 "함수도 값처럼 전달할 수 있다"는 개념이 핵심이고, 이는 이후 정렬(key=), 이벤트 처리 등 다양한 곳에서 응용된다.
  • 람다는 def를 줄여 쓴 한 줄 함수로, 특히 sort(key=...)와 궁합이 좋다.
  • 파일 입출력은 open → 작업 → close 순서를 반드시 기억하자.

Python 클래스(Class) 정리

국비과정에서 배운 파이썬 클래스와 객체지향 개념을 정리했다. 클래스/객체의 기본부터 생성자·소멸자, 클래스 변수와 인스턴스 변수, 상속, 오버라이딩까지 다룬다.

1. 클래스와 객체

  • 클래스(Class): 객체를 만들기 위한 설계도
  • 객체(Object): 클래스로부터 생성된 실제 인스턴스
  • 객체는 속성(프로퍼티/변수)과 행동(메서드)을 가진다.

예제 1) 간단한 클래스 정의와 객체 생성

class Person:
    def __init__(self, name, age):
        self.name = name      # 속성(필드)
        self.age = age

    def introduce(self):      # 메서드
        print(f"안녕하세요, 저는 {self.name}이고 나이는 {self.age}살입니다.")

p1 = Person("Alice", 21)
p2 = Person("Bob", 25)

p1.introduce()
p2.introduce()

__init__은 객체가 생성될 때 자동으로 실행되는 특수 메서드(생성자)다. self는 객체 자기 자신을 가리킨다.

예제 2) 여러 객체 만들기

같은 클래스에서 여러 개의 객체(인스턴스)를 만들 수 있고, 각 객체는 독립적인 속성 값을 가진다.

class Dog:
    def __init__(self, name, breed):
        self.name = name
        self.breed = breed

    def bark(self):
        print(f"{self.name}({self.breed})가 멍멍 짖습니다!")

dog1 = Dog("초코", "푸들")
dog2 = Dog("바둑이", "진돗개")

dog1.bark()
dog2.bark()

2. 생성자와 소멸자

  • 생성자(__init__): 객체가 생성될 때 자동 실행
  • 소멸자(__del__): 객체가 소멸될 때 자동 실행

예제 1) 생성자

class Student:
    def __init__(self, name):
        self.name = name
        print(f"{self.name} 학생이 등록되었습니다.")

s1 = Student("철수")
s2 = Student("영희")

예제 2) 생성자 + 소멸자

class Temp:
    def __init__(self):  # 생성자
        print("객체가 생성되었습니다.")

    def __del__(self):  # 소멸자
        print("객체가 소멸되었습니다.")

t = Temp()  # 객체 생성
print("작업 중...")
print("작업 중...")
print("작업 중...")
del t
print("작업 중...")
print("작업 중...")
print("작업 중...")
print("프로그램 종료")

del t로 객체를 명시적으로 삭제하면 그 시점에 소멸자가 호출된다. (파이썬은 가비지 컬렉션이 있어서 소멸 시점을 완전히 예측하긴 어렵지만, 이 예제처럼 명시적 삭제로는 바로 확인할 수 있다.)


3. 클래스 변수 vs 인스턴스 변수

  • 클래스 변수: 클래스에 소속된 변수. 모든 객체가 공유한다.
  • 인스턴스 변수: 객체마다 따로 존재하는 변수.

예제 1) 클래스 변수로 객체 개수 세기

class Counter:
    count = 0  # 클래스 변수

    def __init__(self, name):
        self.name = name  # 인스턴스 변수
        Counter.count += 1

c1 = Counter("첫 번째")
c2 = Counter("두 번째")

print("전체 객체 수:", Counter.count)
print("c1 이름:", c1.name)
print("c2 이름:", c2.name)

객체가 생성될 때마다 Counter.count가 1씩 증가한다. 이 값은 c1, c2 모두 공유하는 값이라 몇 개의 객체가 만들어졌는지 셀 수 있다.

예제 2) 클래스 변수 확인

class Car:
    wheels = 4  # 모든 차에 공통 적용되는 클래스 변수

    def __init__(self, brand):
        self.brand = brand

car1 = Car("Hyundai")
car2 = Car("Kia")

print("Car의 바퀴 수:", Car.wheels)
print("car1:", car1.brand, car1.wheels)
print("car2:", car2.brand, car2.wheels)

💡 car1.wheels처럼 인스턴스로 클래스 변수에 접근할 수도 있지만, 값을 바꿀 때는 Car.wheels = ...처럼 클래스 이름으로 접근해야 진짜 클래스 변수가 바뀐다. car1.wheels = 6으로 바꾸면 car1에만 새로운 인스턴스 변수가 생기는 것이라 주의가 필요하다.


4. 상속

상속(Inheritance)은 기존 클래스를 확장해서 새로운 클래스를 만드는 것이다. 부모 클래스의 속성과 메서드를 자식 클래스가 물려받는다.

예제 1) 단일 상속

class Animal:
    def speak(self):
        print("동물이 소리를 냅니다.")

class Dog(Animal):
    def speak(self):
        print("멍멍!")

class Cat(Animal):
    def speak(self):
        print("야옹!")

dog = Dog()
cat = Cat()
dog.speak()
cat.speak()

예제 2) super() 활용

super()를 쓰면 자식 클래스에서 부모 클래스의 생성자나 메서드를 호출할 수 있다.

class Person:
    def __init__(self, name):
        self.name = name

    def introduce(self):
        print(f"안녕하세요, 저는 {self.name}입니다.")

class Student(Person):
    def __init__(self, name, major):
        super().__init__(name)  # 부모 생성자 호출
        self.major = major

    def introduce(self):
        super().introduce()
        print(f"제 전공은 {self.major}입니다.")

s = Student("민수", "컴퓨터공학")
s.introduce()

5. 오버라이딩

오버라이딩(Overriding)은 부모 클래스에 있는 메서드를 자식 클래스에서 같은 이름으로 다시 정의해서, 자식 클래스 상황에 맞게 동작을 바꾸는 것이다.

왜 필요할까?

  • 상속받은 기능이 그대로 맞지 않을 때, 자식 클래스가 재정의해서 각자 다른 동작을 하도록 만들 수 있다.
  • 필요한 부분만 자식 클래스에서 수정하면 되니 코드 중복이 줄고 유지보수성이 올라간다.

오버라이딩 규칙

  • 부모 클래스에 같은 이름의 메서드가 있어야 한다.
  • 매개변수 이름과 개수도 동일해야 한다.
  • 자식 클래스에서 새로 정의하면 부모 메서드는 덮어써진다.

예제 1) 오버라이딩 실습

# 부모 클래스
class Animal:
    def speak(self):
        print("소리를 냅니다.")

# 자식 클래스 (오버라이딩)
class Dog(Animal):
    def speak(self):   # 부모의 speak()를 덮어씀
        print("멍멍!")

class Cat(Animal):
    def speak(self):   # 부모의 speak()를 덮어씀
        print("야옹!")

dog = Dog()
cat = Cat()

dog.speak()  # 멍멍!
cat.speak()  # 야옹!

예제 2) super()로 부모 메서드도 함께 사용하기

자식 클래스에서 부모의 메서드를 완전히 대체하지 않고, 부모 동작 + 자식 동작을 함께 쓰고 싶을 때는 super()로 부모 메서드를 먼저 호출한 뒤 추가 동작을 이어 붙인다.

# 부모 클래스
class Animal:
    def speak(self):
        print("소리를 냅니다.")

# 자식 클래스 (오버라이딩)
class Dog(Animal):
    def speak(self):
        super().speak()  # 부모의 메서드 실행
        print("멍멍!")    # 자식의 추가 동작

dog = Dog()
dog.speak()

6. 연습문제

문제 1

Book 클래스를 정의해서 제목(title)과 저자(author)를 속성으로 갖게 하고, 객체를 2개 생성해서 정보를 출력하기.

출력 예시

『파이썬 기초』 - 홍길동
『자바 입문』 - 이몽룡
정답 코드 보기
class Book:
    def __init__(self, title, author):
        self.title = title
        self.author = author

    def info(self):
        print(f"『{self.title}』 - {self.author}")

b1 = Book("파이썬 기초", "홍길동")
b2 = Book("자바 입문", "이몽룡")

b1.info()
b2.info()

문제 2

Student 클래스를 정의해서 이름(name), 국어 점수(kor), 영어 점수(eng)를 속성으로 갖고, 평균 점수를 반환하는 get_avg() 메서드를 만들기. 학생 2명을 생성해서 각각의 정보와 평균 점수를 출력하기.

정답 코드 보기
class Student:
    def __init__(self, name, kor, eng):
        self.name = name
        self.kor = kor
        self.eng = eng

    def get_avg(self):
        return (self.kor + self.eng) / 2

b1 = Student("홍길동", 82, 80)
b2 = Student("김수한", 90, 70)

print(f"이름: {b1.name} / 국어 점수: {b1.kor} / 영어 점수: {b1.eng} "
      f"/ {b1.get_avg()}")

print(f"이름: {b2.name} / 국어 점수: {b2.kor} / 영어 점수: {b2.eng} "
      f"/ {b2.get_avg()}")

문제 3

Animal 클래스를 상속받는 Dog 클래스를 작성하기.

  • Dog는 Animal을 상속받는다.
  • 생성자에서 name을 받아 부모 클래스의 생성자를 호출한다.
  • speak() 메서드를 오버라이드해서 "멍멍!"을 반환하도록 한다.
class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        return "소리를 냅니다."

# 여기에 Dog 클래스를 작성하세요.
정답 코드 보기
class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        return "소리를 냅니다."

class Dog(Animal):
    def __init__(self, name):
        super().__init__(name)

    def speak(self):
        return "멍멍!"

dog = Dog("바둑이")
print("이름:", dog.name)
print("소리:", dog.speak())

마무리

  • 클래스 변수는 모든 객체가 공유, 인스턴스 변수는 객체마다 독립이라는 점이 핵심 차이다.
  • 상속은 "물려받기", 오버라이딩은 "물려받은 걸 자식 상황에 맞게 다시 정의하기"로 구분해서 기억하면 헷갈리지 않는다.
  • super()는 부모의 생성자/메서드를 호출할 때 쓰며, 오버라이딩하면서도 부모 동작을 재사용하고 싶을 때 유용하다.

0개의 댓글