01 클래스의 기본 | ✅저자: 이유정(박사)
🔹 프로그래밍 이념:
이념 | 설명 | 비유된 설명 | 대표적인 언어 예시 |
---|---|---|---|
명령형 <br>프로그래밍 | 명령문을 순서대로 실행 → 컴퓨터에게 '무엇을 어떻게 할지' 하나씩 지시 | “프린트 해라”, “입력 받아라” 식의 지시문 | C, Java, JavaScript, Python |
절차적 <br>프로그래밍 | 반복되는 코드를 함수로 묶자 | "반복하지 말고 함수를 만들어 써라"는 율법 | C, Pascal, BASIC, Fortran, Python |
함수형 <br>프로그래밍 | 수학처럼 ‘순수 함수(pure function)’만 사용하자 | "부작용 없는 함수만 써야 한다"는 믿음 | Haskell, Lisp, Scala, Elixir, F#, Python |
선언형 <br>프로그래밍 ................... | 무엇을 만들지만 선언, 어떻게 만들지는 신경 안 씀 | HTML처럼 결과만 선언 (<h1>제목</h1> ) |
SQL, HTML, CSS, Prolog, Python |
파이썬(Python)은 매우 유연한 언어로, 명령형, 절차적, 함수형, 선언형 프로그래밍을 모두 지원하는 멀티 패러다임 언어입니다. |
-
명령형 (Imperative):
- "무엇을 어떻게 할지"를 명령처럼 작성
- 상태 변경과 반복문 중심
- 대부분의 범용 언어가 포함됨 (예: Python, Java)
-
절차적 (Procedural):
- 명령형의 하위 개념, 함수(프로시저) 중심으로 작성
- 코드의 재사용성과 구조화 강조
-
함수형 (Functional):
- 상태 변경 없이 순수 함수만 사용하는 방식
- 변수 변경 없음, 재귀, 고차 함수 강조
-
선언형 (Declarative):
- "무엇을 할 것인지"만 기술 (어떻게는 신경 안 씀)
- 예: SQL에서
SELECT
문 → 데이터를 어떻게 찾는지는 DB 엔진이 처리
💬 추가 설명: 중요하지는 않음
-
Haskell (해스켈):
함수형 프로그래밍의 대표 주자. 수학자 Haskell Curry의 이름에서 따옴. -
Lisp (리습):
"LISt Processing"의 약자. 괄호 많은 언어로 유명함. -
Scala (스칼라):
"Scalable Language"에서 유래. 자바와 호환되며 함수형 + 객체지향 혼합. -
Elixir (엘릭서):
동시성(concurrency) 처리를 위해 만들어진 함수형 언어.
함수를 너무 많이 만들면 생기는 문제:
- 코드가 복잡해져서 어떤 함수가 어떤 일을 하는지 파악하기 어렵고
- 함수를 고칠 때 영향 받는 부분이 너무 많아져서 수정이 위험해짐
그래서 “함수를 어떻게 하면 잘 정리할 수 있을까?” 고민하게 됩니다. 이후 개발자들이 찾은 해결책: '카테고리로 묶자'
예시 비유: 서점
- 수많은 책이 있을 때 분야별로(컴퓨터, 경제, 요리) 정리해 두면 찾기 쉬움
- 마찬가지로, 함수를 관심사에 따라 묶으면 개발도 쉬워짐
◽ 2가지 묶는 방법:
분류 기준 | 설명 | 예 |
---|---|---|
관심사 기준 | 수학 관련 함수는 math 로 묶자 |
math.sin() , math.pi |
주어(객체) 기준 | "누가 이 동작을 하느냐?"를 기준으로 묶자 | car.start() , user.login() |
객체지향 프로그래밍(OOP)이란?
- “주어(= 객체)를 기준으로 함수와 변수들을 묶자!”
- 객체 = 현실의 사물처럼 속성과 행동을 가진 덩어리
- 예: 자동차 객체 →
속성: 색상, 속도
,행동: 출발, 정지
class Car:
def __init__(self, color): # 객체(인스턴스) 초기화
self.color = color # 속성적용
def start(self):
print(f"{self.color} 자동차가 출발합니다.")
이렇게 변수를 묶고 함수를 묶은 구조가 "클래스(class)"이며,
클래스는 객체지향 프로그래밍의 핵심 도구입니다.
📝 문제1] 다음 중 객체지향 프로그래밍(OOP)의 특징으로 올바르지 않은 것은?
A. 캡슐화
B. 상속
C. 절차 중심
D. 다형성
✅ 정답: C
🔹 클래스(Class)
- 클래스는 설계도입니다.
예) "학생(Student)"이라는 설계도(클래스)를 만들면, "길동", "짱구" 같은 실제 학생들을 만들 수 있습니다. - 이 설계도를 바탕으로 만든 실제 결과물은 객체(Object) 또는 인스턴스(Instance)라고 합니다.
📖 문법, 구문(syntax):
class 클래스이름:
def __init__(self, 변수들...):
self.변수1 = 변수1
self.변수2 = 변수2
...
def 함수이름(self):
# 기능 정의
📝 문제1] 파이썬에서 클래스를 정의할 때 사용하는 키워드는?
A. def
B. class
C. new
D. function
✅ 정답: B
📝 문제2] 다음 중 클래스
에 대한 설명으로 올바른 것은?
A. 데이터를 저장하는 저장소이다
B. 메서드만을 정의하는 구조이다
C. 객체를 만들기 위한 설계도이다
D. 리스트와 딕셔너리를 대체하는 구조이다
✅ 정답: C
📝 문제3] 다음 중 파이썬 클래스 정의의 문법 구조로 올바른 것은?
A.
def MyClass():
class:
pass
B.
class MyClass[]
def __init__():
pass
C.
class MyClass:
def __init__(self):
pass
D.
create class MyClass:
function init():
pass
✅ 정답: C
◽ 생성자란?
생성자(Constructor)는 클래스에서 객체가 생성될 때 자동으로
실행되는 특수한 메서드입니다.
파이썬에서는 생성자를 __init__() 이라는 이름으로 사용하며,
객체의 속성 초기화 및 준비 작업을 수행합니다.
- 객체가 만들어질 때 자동으로 호출됩니다.
- 주로 변수 초기화, 기본값 설정, 유효성 검사 등에 사용됩니다.
◽ 왜 사용할까요?
- 객체가 만들어질 때 자동으로 초기 설정을 하기 위해
- 클래스 외부에서 매번 초기화 코드를 작성하지 않아도 되어 코드가 간결하고 일관성 있음
- 객체를 만들 때 필수값이나 조건을 강제할 수 있음
◽ __init__
이란?
__init__
은 클래스에서 객체(인스턴스)가 만들어질 때 자동으로 실행되는 함수입니다."initialize(초기화하다)"
의 줄임말이에요.- 그래서
__init__
은 객체를 초기화하는 함수라고도 불러요.
📝 문제1] 다음 중 생성자 메서드로 올바른 것은?
A. __start__()
B. __main__()
C. __init__()
D. __create__()
✅ 정답: C
📝 문제2] 다음 중 __init__()
메서드에 대한 설명으로 올바른 것은?
A. 클래스 외부에서 직접 호출하여 객체를 생성하는 함수이다.
B. 객체 생성 후 자동으로 호출되는 클래스 외부 함수이다.
C. 객체가 생성될 때 자동으로 실행되는 클래스 내부의 특수 메서드이다.
D. 클래스 내부에서만 사용 가능한 일반 함수이며 객체 생성과 무관하다.
✅ 정답: C
- A는 "외부에서 직접 호출"이 아니라
객체 생성 시 자동 호출
이므로 틀림. - B는
"클래스 외부 함수"
가 아님. - D는 일반 함수가 아니라 생성자 역할을 하는 특수 메서드임.
📝 문제3] 생성자 __init__()
의 주된 목적으로 가장 적절한 것은?
A. 클래스에 메서드를 추가하기 위해 사용된다.
B. 객체를 생성할 때 클래스를 메모리에 로드하기 위해 사용된다.
C. 객체가 삭제될 때 자동으로 실행되어 리소스를 해제한다.
D. 객체 생성 시 필요한 초기값을 설정하고 인스턴스 변수를 초기화한다.
✅ 정답: D
- A는 클래스 정의 구조와 관련된 설명.
- B는 생성자가 아닌 클래스 로딩 메커니즘 관련 설명.
- C는 소멸자
__del__()
의 역할.
◽ 객체란?
객체는 현실 세계의 사물이나 개념을 파이썬 코드로 표현한 것입니다.
클래스라는 설계도를 바탕으로 만들어진 실제 사용 가능한
실체(인스턴스)이며,
속성(데이터)과 기능(동작)을 함께 가지고 있습니다.
하나의 클래스에서 여러 개의 객체를 만들 수 있습니다.
◽ 언제 호출되나요? 객체만들기
class Student:
def __init__(self, name):
self.name = name
# 객체 만들기
student1 = Student("길동")
위에서 Student("길동")
을 실행하면, 자동으로 내부의 __init__()
함수가 호출되어요.
결과적으로 student1.name
은 "길동"
이 됩니다.
즉, student1
은 Student
클래스의 인스턴스(instance)이며,
이 인스턴스는 객체(object)입니다.
◽ 왜 __init__
이 필요할까?
- 객체를 만들자마자 값을 넣을 수 있음
student1 = Student("길동")
→ 자동으로 name 저장!
- 필수 데이터를 넣도록 강제할 수 있음
- name, 점수 등 꼭 필요한 데이터를
__init__()
에서 받아 저장하게 함
- name, 점수 등 꼭 필요한 데이터를
- 객체의 상태를 시작부터 준비할 수 있음
- 예: 학생의 이름과 점수를 딱 정해놓고 시작
◽ self
란?
self
는 객체 자신을 가리키는 말입니다.- 객체가 가진 변수나 함수에 접근할 때 반드시 사용합니다.
</> 예시:
class Dog:
def __init__(self, name):
self.name = name
puppy = Dog("초코")
print(puppy.name) # 출력: 초코
Dog("초코")
를 하면__init__
이 실행돼서self.name = "초코"
가 저장됨puppy.name
은"초코"
◽ __init__
을 꼭 사용하는가?
- 아니요.
__init__
은 객체를 만들자마자 자동으로 초기값을 주고 싶을 때 사용하는 것이고, - 아무 초기값 없이 쓸 거면 안 써도 됩니다.
class Dog:
pass
puppy = Dog()
하지만 실제 개발에서는 대부분의 클래스에 __init__
을 씁니다, 왜냐면 객체마다 다른 값을 넣어야 합니다.
📝 문제1] 객체를 생성하는 코드로 올바른 것은? (클래스명이 Dog일 때)
A. Dog[]
B. new Dog()
C. Dog()
D. create Dog()
✅ 정답: C
📝 문제2] 다음 중 "객체"의 정의로 가장 올바른 것은?
A. 메서드만을 포함한 독립적인 코드 블록이다.
B. 클래스를 설계하기 위해 사용하는 함수이다.
C. 클래스를 기반으로 생성된 실체(실제 데이터와 기능을 지닌 것)이다.
D. 모든 함수의 실행 결과로 자동 생성되는 값이다.
✅ 정답: C
- A는 클래스의 메서드 설명임.
- B는 객체가 아니라 클래스 설명.
- D는 함수 결과는 객체일 수 있지만, 객체의 정의는 아님.
📝 문제3] 다음 중 객체 생성 시 __init__()
메서드가 호출되는 시점은?
A. 클래스를 정의할 때 자동으로 실행된다.
B. 객체를 삭제할 때 자동으로 호출된다.
C. 객체를 생성할 때 자동으로 호출된다.
D. 객체 내의 메서드를 호출할 때 자동으로 실행된다.
✅ 정답: C
- A는 클래스 정의 시점, B는 소멸자, D는 일반 메서드 실행 조건.
📝 문제4] 다음 중 self
키워드에 대한 설명으로 가장 정확한 것은?
A. 클래스 외부에서 인스턴스를 참조할 때 사용하는 키워드이다.
B. 객체가 삭제될 때 해당 메모리를 비우기 위한 예약어이다.
C. 인스턴스 자신을 참조하는 매개변수로, 클래스 내부 메서드에서 사용된다.
D. __init__()
함수가 실행되지 않도록 하는 예약어이다.
✅ 정답: C
- A는 외부 접근 방식과 혼동.
- B는
del
키워드와 혼동. - D는 잘못된 기술로
self
는 실행과 무관.
</> 예시: 학생(Student) 클래스 만들기:
class Student:
def __init__(self, name, korean, english, math, science):
self.name = name
self.korean = korean
self.english = english
self.math = math
self.science = science
def get_sum(self):
return self.korean + self.english + self.math + self.science
def get_average(self):
return self.get_sum() / 4
def print_info(self):
print(f"{self.name}\t총점: {self.get_sum()}\t평균: {self.get_average():.2f}")
#출력예시) 홍길동 총점: 350 평균: 87.50
- 속성 할당 (Attribute Assignment):
self.name
처럼 클래스(객체)의 속성에 값을 저장하는 것을 말합니다. - 인스턴스 변수 초기화 (Instance Variable Initialization): 객체를 생성할 때,
__init__
을 통해 인스턴스 변수에 초기값을 설정하는 작업입니다.
객체 만들기 (인스턴스 생성)
student1 = Student("길동", 90, 85, 88, 92)
student2 = Student("짱구", 80, 75, 78, 85)
student1.print_info()
student2.print_info()
print(type(student1))
🖨️ 출력 결과:
길동 총점: 355 평균: 88.75
짱구 총점: 318 평균: 79.50
<class '__main__.Student'>
- 클래스는 관련 데이터(변수)와 기능(함수)을 묶는 틀이에요.
__init__()
은 초기값을 설정하는 함수이며, 항상self
가 첫 번째로 와야 합니다.- 객체를 만들고 나면
.변수
,.함수()
형식으로 접근합니다.
📝 문제1] 다음 중 속성 할당
의 예로 올바른 것은?
A. self.age + 10
B. age = self.10
C. self.age = 10
D. 10 = self.age
✅ 정답: C
📝 문제2] 다음 코드에서 name
과 age
는 무엇인가?
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
A. 클래스 변수
B. 지역 변수
C. 인스턴스 변수
D. 전역 변수
✅ 정답: C
📝 문제3] 아래 코드를 통해 생성된 person1
은 어떤 개념에 해당하는가?
class Person:
def __init__(self, name):
self.name = name
person1 = Person("Alice")```
A. 함수
B. 모듈
C. 객체
D. 메서드
✅ 정답: C
----
매개변수 갯수는 정확히 지켜야 합니다. 함수와 같이 매개변수의 갯수가 인자의 갯수과 일치하지 않으면 TypeError가 발생합니다.
</> 예시코드:
```python
# 매개변수 5개 → 정확히 맞게 호출해야합니다.
s1 = Student("길동", 90, 85, 88, 92) # 정상
# ❌ 매개변수 4개 → 오류 발생
s2 = Student("영희", 80, 75, 90)
# TypeError: Student.__init__() missing 1 required positional argument: 'sci'
기본값 설정 → 일부는 생략 가능하게 만들기
def __init__(self, name, kor=0, eng=0, math=0, sci=0):
...
s1 = Student("길동") # 나머지는 자동으로 0 들어감
키워드 인자 사용 → 순서를 신경 안 써도 됨
s2 = Student(name="영희", math=100, eng=90, kor=85, sci=88)
단, 결과가 정해져 있을경우에만 사용
가변 인자 *args 사용 (비추천, 정확성 떨어짐)
def __init__(self, *args):
self.name = args[0]
self.kor = args[1]
...
너무 자유로워져서 실수를 방지하기 어려워 비추천
📝 문제1] 클래스에서 객체마다 고유하게 가지는 데이터는 무엇이라 부르는가?
A. 클래스 변수
B. 정적 변수
C. 인스턴스 변수
D. 공유 변수
✅ 정답: C
📝 문제2] 다음 중 객체를 설명하는 표현으로 가장 적절한 것은?
A. 함수의 집합
B. 클래스의 인스턴스
C. 변수의 묶음
D. 연산의 결과
✅ 정답: B
📝 문제3] 다음 코드 실행 시 발생하는 오류의 원인으로 가장 적절한 것은?
def greet(name, age=20):
print(f"{name}는 {age}살입니다.")
greet(age=25, "홍길동")
A. age가 기본값으로 이미 정의되어 있어서 오류
B. 위치 인자보다 키워드 인자를 먼저 사용할 수 없기 때문에 오류
C. print 문법이 잘못되어 오류
D. 함수 정의에 기본값이 없어서 오류 발생
✅ 정답: B 파이썬에서는 위치 인자(positional argument)가 먼저 오고, 그 뒤에 키워드 인자(keyword argument)를 사용해야 합니다. 위 코드는 순서를 잘못 지정해 오류 발생.
📝 문제4] 다음 코드 실행 시 어떤 오류가 발생하는가?
def add(x, y):
return x + y
add(5, y=10)
A. 매개변수 x가 중복되어 오류 발생
B. 함수가 반환값이 없어서 오류
C. 위치 인자와 키워드 인자가 모두 올바르게 지정되어 오류 없음
D. x에 대한 값을 두 번 전달했기 때문에 오류 발생
✅ 정답: C
add(5, y=10)
에서 5
는 x
에, y=10
은 y
에 전달되므로 문법적으로 오류 없음. 함수는 정상 동작하며 15
를 반환합니다.
◽ __init__
생성자 없는 클래스
❌ </> __init__
없을때 예시코드1 :
class Dog:
pass # 생성자 없음
# 객체 생성
puppy1 = Dog()
puppy2 = Dog()
# 객체 생성 후 수동으로 속성 추가
puppy1.name = "초코"
puppy1.age = 2
puppy2.name = "보리"
puppy2.age = 3
# 출력
print(puppy1.name, puppy1.age) # 출력: 초코 2
print(puppy2.name, puppy2.age) # 출력: 보리 3
- ✔ 객체에 속성을 붙일 수는 있음
- ❌ 속성 누락, 오타, 반복 등 실수 위험이 큼
❌ </> __init__
없을때 예시코드2 : 클래스 안에 변수선언
class Dog:
name = "기본이름"
age = 1
a = Dog()
b = Dog()
print(a.name) # 기본이름
print(b.age) # 1
- ✔ 모든 객체가 같은 값을 가질 때는 유용
- ❌ 객체마다 다른 값을 설정하려면 직접 덮어써야 함
❌ </> __init__
없을때 예시코드3 : 초기화 대신 메서드 생성
class Dog:
def set_info(self, name, age):
self.name = name # 속성 할당
self.age = age
puppy1 = Dog()
puppy1.set_info("초코", 2) # 인스턴스 메서드 호출
puppy2 = Dog()
puppy2.set_info("보리", 3)
- ✔
__init__
없이 메서드로 초기값 설정 가능 - ❌ 객체 생성 시 바로 초기값을 줄 수 없고, 별도 메서드 호출이 필요함
◽ 책(Book) 클래스
</> 예시: 책(Book) 클래스 만들기:
class Book:
def __init__(self, title, author, year):
self.title = title
self.author = author
self.year = year
print("책 객체가 생성되었습니다.") # 이건 자동 실행됨
def info(self):
return f"'{self.title}' by {self.author} ({self.year})"
print(f"책 제목: {self.title}") # 호출해야 실행됨
# 인스턴스 생성
book1 = Book("파이썬 기초", "홍길동", 2024)
book2 = Book("클래스의 이해", "신짱구", 2023)
# 객체는 무조건 생성해야함/ 클래스 함수 안쪽에 print출력을 위한 테스트
book3 = Book("파이썬 입문서","이지은", 2024)
# 출력
print(book1.info())
print(book2.info())
# book1.info()를 호출하지 않으면 아래는 출력되지 않음
book1.info() # info함수를 직접 호출
🖨️ 출력 결과:
'파이썬 기초' by 홍길동 (2024)
'클래스의 이해' by 신짱구 (2023)
◽ 사용자(User) 클래스
</> 예시: 사용자(User) 클래스 만들기:
class User:
def __init__(self, username, email):
self.username = username
self.email = email
def greet(self):
return f"안녕하세요, {self.username}님! 이메일: {self.email}"
# 인스턴스 생성
user1 = User("eunice98", "eunice@example.com")
user2 = User("admin", "admin@example.com")
# 출력
print(user1.greet())
print(user2.greet())
🖨️ 출력 결과:
안녕하세요, eunice75님! 이메일: eunice@example.com
안녕하세요, admin님! 이메일: admin@example.com
Django 클래스는 __init__()
을 대부분 직접 만들지 않습니다.
Django가 자동으로 __init__()
을 정의해서 제공하기 때문이에요.
- 예:
models.Model
,forms.Form
,views.View
등은 이미 내부에__init__()
이 정의돼 있음 - 그래서 우리가 직접
__init__()
을 안 써도,
title = models.CharField(max_length=100)
이런 식으로 객체를 생성할 수 있는 거예요!
📝 문제 1] 생성자 없이 메서드 사용하기 한 학생의 이름과 점수를 객체를 만든 후 메서드로 저장하세요.
🖨️ 출력결과:
이름: 지민, 점수: 90
✅ 정답코드:
class Student:
def set_info(self, name, score):
self.name = name
self.score = score
s1 = Student()
s1.set_info("지민", 90)
print(f"이름: {s1.name}, 점수: {s1.score}")
🔍 해설:
__init__
없이set_info()
메서드로 값을 저장self.name = name
을 통해 속성(인스턴스 변수) 생성 및 저장
📝 문제 2] 생성자 사용하기 다음 코드에서 생성자를 사용하여 이름과 나이를 저장하고 출력하세요.
🖨️ 출력결과:
이름: 해린, 나이: 21
✅ 정답코드:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p = Person("해린", 21)
print(f"이름: {p.name}, 나이: {p.age}")
🔍 해설:
__init__
생성자를 통해 객체 생성 시 값을 전달함p = Person("해린", 21)
에서 바로 초기화됨
📝 문제 3] 메서드로 연산 기능 추가 객체 내부에 점수 3개를 넣고, 총점과 평균을 메서드로 구하세요.
🖨️ 출력결과:
총점: 255
평균: 85.0
✅ 정답코드:
class Student:
def __init__(self, name, scores):
self.name = name
self.scores = scores
def get_sum(self):
return sum(self.scores)
def get_avg(self):
return sum(self.scores) / len(self.scores)
s1 = Student("민지", [80, 90, 85])
print("총점:", s1.get_sum())
print("평균:", s1.get_avg())
🔍 해설:
- 리스트로 점수를 저장하고
sum()
함수로 총점 계산 - 평균은 총합을 개수로 나눔
📝 문제 4] 객체 여러 개 만들기 강아지 두 마리를 만들어서 이름과 나이를 다르게 저장하고 출력하세요.
🖨️ 출력결과:
강아지 이름: 초코, 나이: 2
강아지 이름: 보리, 나이: 3
✅ 정답코드:
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
d1 = Dog("초코", 2)
d2 = Dog("보리", 3)
print(f"강아지 이름: {d1.name}, 나이: {d1.age}")
print(f"강아지 이름: {d2.name}, 나이: {d2.age}")
문제 5] 조건에 따라 출력 달라지게 하기 학생 객체를 만들어 점수가 60점 이상이면 “합격”, 아니면 “불합격”을 출력하세요.
🖨️ 출력결과:
이름: 수아, 결과: 합격
이름: 윤기, 결과: 불합격
✅ 정답코드:
class Student:
def __init__(self, name, score):
self.name = name
self.score = score
def check_pass(self):
return "합격" if self.score >= 60 else "불합격"
s1 = Student("수아", 85)
s2 = Student("윤기", 45)
print(f"이름: {s1.name}, 결과: {s1.check_pass()}")
print(f"이름: {s2.name}, 결과: {s2.check_pass()}")
🔍 해설:
check_pass()
메서드는 조건문 사용- 점수에 따라 다른 결과 출력
문제 6] 생성자 없이 속성 누락 시 문제 확인 아래 코드는 오류 없이 실행될까요? 왜 그런가요?
class Car:
pass
my_car = Car()
print(my_car.color)
🖨️ 출력결과:
AttributeError: 'Car' object has no attribute 'color'
✅ 정답코드:
# 위 코드는 오류 발생 → 수정 방법:
class Car:
def __init__(self, color):
self.color = color
my_car = Car("red")
print(my_car.color)
🔍 해설:
__init__
이 없고color
속성도 직접 할당하지 않았기 때문에 오류 발생- 생성자 또는
my_car.color = 'red'
처럼 수동 할당 필요
🔹 Django의 클래스
models.py – 클래스 = 데이터베이스 테이블
모델 클래스 정의 (models.py)
from django.db import models
class Article(models.Model): # Article 테이블 생성
title = models.CharField(max_length=100) # 속성적용
content = models.TextField() # 아래 함수를 위한 속성적용
created_at = models.DateTimeField(auto_now_add=True)
def summary(self):
return self.content[:50] # 50자 이내로 작성
CharField
는 짧은 문자열 필드로 반드시max_length
지정 필요합니다.TextField
는 긴 텍스트 (본문, 댓글 등)으로 제한없습니다.(DB 허용만큼)
인스턴스 생성 예 (views.py 또는 Django shell)
from django.shortcuts import render
from .models import Article
def create_article_view(request):
article = Article.objects.create(
title="장고 클래스 예제",
content="이 내용은 최대 50자 요약됩니다."
)
return render(request, 'article_created.html', {'article': article})
결과 확인 (article_created.html)
<!-- templates/article_created.html -->
<h1>게시글 생성 완료</h1>
<p>제목: {{ article.title }}</p>
<p>요약: {{ article.summary }}</p>
title = models.CharField(max_length=100)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
이런 것들을 필드 클래스 인스턴스라고 부르며 대부분 규격화 되어 있지만 필요에 따라 커스터마이징도 가능합니다.
◽ 데이터 필드는 다음과 같은 표준 필드 클래스로 제공합니다:
필드 클래스 | 설명 |
---|---|
CharField |
문자열 필드 (max_length 필수) |
TextField |
긴 텍스트 |
IntegerField |
정수 |
DateTimeField |
날짜+시간 |
BooleanField |
True/False |
EmailField |
이메일 형식 자동 검증 |
ForeignKey |
다른 모델과 연결된 관계형 키 |
필드들은 공통적으로 이런 속성들을 가짐: |
null=True
→ DB에서 NULL 허용blank=True
→ 폼에서 빈칸 허용default='값'
→ 기본값verbose_name='레이블명'
→ 관리자 페이지용 레이블
title = models.CharField(max_length=100, blank=True, verbose_name="게시글 제목")
◽ Django 관련 예시2
forms.py
– 클래스 = 사용자 입력 폼
폼 클래스 정의 (
forms.py)
from django import forms
class ContactForm(forms.Form):
name = forms.CharField(label='이름', max_length=50)
email = forms.EmailField(label='이메일')
message = forms.CharField(label='메시지', widget=forms.Textarea)
인스턴스 생성 및 처리 (views.p)
# views.py
from django.shortcuts import render
from .forms import ContactForm
def contact_view(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
# 폼에서 데이터 꺼내기
name = form.cleaned_data['name']
email = form.cleaned_data['email']
message = form.cleaned_data['message']
return render(request, 'contact_success.html', {'name': name})
else:
form = ContactForm()
return render(request, 'contact_form.html', {'form': form})
폼 출력 템플릿 (contact_form.html)
<!-- templates/contact_form.html -->
<h1>문의하기</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">전송</button>
</form>
성공 템플릿 (contact_success.html)
<!-- templates/contact_success.html -->
<h2>감사합니다, {{ name }}님!</h2>
<p>문의가 성공적으로 접수되었습니다.</p>
◽ 매직 메서드(Magic Methods) 또는 더블 언더스코어 메서드(Dunder Methods, method)
- __이름__ 형식의 특별한 이름을 가진 메서드들
- 파이썬 내부 동작에 연결된 함수입니다.
- 우리가 직접 호출하지 않아도, 특정 상황에서 자동으로 호출됩니다.
메서드 이름 | 용도 및 설명 | 예시 |
---|---|---|
__init__ |
객체 초기화 메서드 (생성자) | def __init__(self, *args, **kwargs): |
__str__ |
객체의 문자열 표현 (관리자 페이지, shell 등에서 출력 형태) | return self.title |
__eq__ |
두 객체의 비교(==) 동작 정의 | def __eq__(self, other): return self.id == other.id |
__len__ |
객체의 길이 반환 (len(obj) 호출 시) |
예: 댓글 개수 등 |
__getitem__ |
인덱스로 접근 (obj[0] ) |
리스트/쿼리셋 흉내 낼 때 |
__bool__ |
객체의 참/거짓 여부 | def __bool__(self): return self.is_active |
__repr__ |
객체의 개발자용 문자열 표현 (디버깅용) | return f"<Post: {self.title}>" |
__lt__ , __gt__ |
<, > 비교 연산자 오버라이딩 | 정렬 기준 정의 시 사용 |
__setitem__ |
인덱스로 값 설정 (obj[0] = value ) |
커스텀 컨테이너 |
__call__ |
함수처럼 객체 호출 가능하게 만듬 (obj() ) |
커스텀 폼 검증기 등 |
__getattr__ |
없는 속성에 접근 시 호출됨 | 예: 접근 로깅 |
__setattr__ |
속성 설정할 때 호출됨 (obj.x = 10 ) |
속성 제어 |
__del__ |
객체 삭제 시 수행 | 일반적으로 Django에서는 자주 쓰지 않음 |
◽ 실무에서 꼭 사용하는 매직 메서드 예제
</> 예시코드: __str__
class Post(models.Model):
title = models.CharField(max_length=100)
def __str__(self):
return self.title
Admin 페이지, print(Post.objects.first()) 등에 영향을 줍니다.
없으면 Post object (1)처럼 기본 출력됩니다.
결과: 관리자 페이지나 print(Article.objects.first())
에서 보기 좋게 표시
[게시글] Django 시작하기
</> 예시코드: __init__
# models.py
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=100)
def __init__(self, *args, **kwargs):
print("Article 객체 생성됨")
super().__init__(*args, **kwargs)
모델 객체 생성 시 추가 동작이 필요할 때 사용. 반드시 super() 호출이
필요함.
결과: 객체 생성 시 콘솔에 메시지 출력됨
>>> Article(title="테스트 제목")
Article 객체 생성됨
</> 예시코드: __eq__
class Article(models.Model):
title = models.CharField(max_length=100)
def __eq__(self, other):
if isinstance(other, Article):
return self.pk == other.pk
return False
두 객체가 같은지 비교할 때. 보통 pk 기준으로 비교
# 사용 예
a1 = Article.objects.get(id=1)
a2 = Article.objects.get(id=1)
print(a1 == a2) # True
</> 예시코드: __len__
# views.py
from .models import Article
def article_count_view(request):
articles = Article.objects.all()
print(len(articles)) # 내부적으로 __len__ 사용
모델 인스턴스에는 잘 쓰지 않고, QuerySet 클래스에서 자주 사용됨.
결과: __len__()
은 QuerySet에 정의되어 있음 → 자동 동작
</> 예시코드: __getitem__
# views.py
def sliced_articles(request):
articles = Article.objects.all()
recent_three = articles[:3] # QuerySet에서 __getitem__ 호출
마찬가지로 QuerySet 객체에서 슬라이싱이 가능하게 해주는 매직 메서드.
</> 예시코드: __repr__
class Article(models.Model):
title = models.CharField(max_length=100)
def __repr__(self):
return f"<Article id={self.id} title={self.title!r}>"
디버깅 시 개발자 친화적 정보를 제공. Django 모델에서 __str__과 함께
많이 사용.
>>> repr(Article.objects.get(id=1))
< Article id=1 title='Django 시작하기' >
</> 예시코드: __bool__
# views.py
def check_articles(request):
articles = Article.objects.all()
if articles: # 내부적으로 __bool__ 실행
print("게시글이 존재합니다.")
else:
print("게시글이 없습니다.")
QuerySet에 결과가 있는지 여부를 확인할 때 내부적으로 호출됨.