우와한 개발자

[Python] 클래스(class)와 객체(object) - 구조, 네임스페이스, self

by 우와한개발자

1. 기본 개념

  • 클래스(Class) : 객체를 만들기 위한 틀(Template, Blueprint, Specification)
  • 객체(Object) : 클래스의 인스턴스(Instance)45)
  • 객체의 명사적 특성 : 데이터(Data), 변수(Variable), 필드(Field), 속성(Attribute)
  • 객체의 동사적 특성 : 행위(Behavior), 함수(Function), 메서드(Method), 기능 (Operation)

 

2. 클래스와 객체 구조

  • 클래스 영역과 인스턴스 영역이 분리되어있음

1) 클래스 영역

  • 클래스의 멤버 영역 : 변수와 메서드 참조(주소)를 보관
  • 메서드는 코드 실행 영역의 주소를 참조하는 방식
  • 클래스의 코드 실행 영역 : 메서드의 실제 코드가 존재

 

2) 인스턴스 영역

  • 인스턴스 변수만 보관
  • 메서드 코드는 없음 (호출 시 클래스 영역에서 찾아서 실행)
  • 인스턴스마다 독립적인 네임스페이스를 가짐 → p1.__dict__로 확인 가능
  • 같은 클래스로 만든 객체라도 인스턴스 변수는 서로 영향을 주지 않음

 

2. 클래스 정의과 객체 생성

1) 클래스 정의

  • CLASS 키워드 이용하고 클래스명은 카멜 표기법(Camel Case) 사용
class 클래스명:

 

2) 객체 생성

  • 클래스명에 ()를 붙여 호출하면 객체(인스턴스)가 생성됨
# 객체 생성
p1 = Person()       # 인자 없는 경우
p1 = Person("홍길동")  # 인자 있는 경우 (__init__ 호출)

# 생성된 객체 사용
print(p1.name)      # 변수 접근
p1.print_info()     # 메서드 호출

 

3. 네임스페이스와 변수 참조

1) 네임 스페이스

  • 클래스 객체와 인스턴스 객체의 이름 공간(namespace)이 분리되어 있음.

 

2) 변수 참조

  • 클래스 변수와 인스턴스 변수는 클래스 저장 영역이 다름
  • 객체의 변수가 새로운 값을 할당받게 된다면 클래스 영역 의 변수가 수정되는 것이 아니고 객체의 이름공간에 변수가 추가됨
  • 자바 스크립트처럼 동적으로 멤버 추가 가능
class Person:
    name = '홍길동'

p1 = Person()
p1.name = 'hongkildong'   # 클래스 변수 수정 X → p1에 새 변수 추가

print(Person.name)   # '홍길동'      ← 클래스 변수 그대로
print(p1.name)       # 'hongkildong' ← p1 인스턴스 변수

 

3) 변수 탐색

  • 인스턴스에서 변수를 찾을 때 아래 순서로 탐색하며, 먼저 찾으면 탐색을 멈춤
  • 순서 : 인스턴스 네임스페이스 → 클래스 네임스페이스 → 부모 클래스 네임스페이스
class Person:
    name = '홍길동'   # 클래스 네임스페이스

p1 = Person()

# p1에 name이 없음 → 클래스에서 찾음
print(p1.name)   # '홍길동'

p1.name = 'hongkildong'   # p1 네임스페이스에 name 추가

# 이제 p1에 name이 있음 → 클래스까지 안 가고 바로 반환
print(p1.name)   # 'hongkildong'

 

4. 인스턴스 메서드와 self

1) 인스턴스 메서드

  • 인스턴스는 자기 변수만 갖고, 메서드는 클래스에서 빌려 쓰는 구조
  • 클래스의 함수(메서드)는 실행할 코드 영역을 가리키는 주소를 참조하기 때문에 코드 안에서 변수를 참조하면 클래스 변수인지 인스턴스 변수인지 구분할 수 없어 첫번째 인자로 self
class Person:
    name='홍길동'
    gender='남자'

    def print_info():
        print('Person 객체입니다.')

# TypeError: Person.print_info() takes 0 positional arguments but 1 was given
# 코드 안에서 변수를 참조하면 클래스 변수인지 인스턴스 변수인지 구분할 수 없기 때문
p1.print_info() 
p1.print_info()          # 내부적으로 아래와 동일
Person.print_info(p1)    # p1을 첫 번째 인자로 자동 전달

 

2) self

  • 자신 객체를 의미
  • 클래스의 멤버가 아닌 자기자신 객체의 멤버를 참조할수 있도록 하기위해 인스턴스 메서드의 첫번째 인자는 self여야함

블로그의 정보

우와한개발자 님의 블로그

우와한개발자

활동하기