클래스 (class)

클래스는 객체의 구조와 행동을 정의 한다.
객체의 클래스는 초기화를 통해 제어 한다.
클래스는 복잡한 문제를 다루기 쉽도록 한다.

✔️ class, 객체(object), 인스턴스(instance)
객체(object) 는 소프트웨어 세계에 구현할 대상이고, 이를 구현하기 위한 설계도가 class 이며, 설계도에 따라 소프트웨어 세계에 구현된 실체가 인스턴스(instance) 이다. 보통 인스턴스를 객체라고도 부른다.

# 클래스 정의 (class)

class 키워드를 사용하여 새로운 클래스를 선언한다.
파이썬 대부분이 네이밍컨벤션이 단어와 단어 사이에 _를 넣는다면 클래스의 네이명 컨벤션은 CamelCase로 한다.

1
2
3
class ClassInfo:
def __init__(self):
print("초기화")

생성자와 인스턴스

인스턴스: 변수에 클래스를 할당 하는 것. 객체가 메모리상에 할당이 되는 것
생성자: 변수에 클래스를 할당할 때 쓰인다. 인스턴스 할 때 사용하는 것

1
2
3
4
5
class ClassInfo:
def __init__(self):
print("초기화")

cInfo = ClassInfo()

cInfo : 변수
ClassInfo() : 생성자

# 초기화자(initializing)

객체(인스턴스)가 생성되고 나면 __init__ 메소드를 호출하여 객체에서 사용할 값들을 초기화 한다.
객체에 초기화된 변수들, 인스턴스 변수 들을 호출 할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
class UserInfo:

def __init__(self, name, height, weight):
self.name = name
self.height = height
self.weight = weight

user1 = UserInfo("Kim", 190, 80)

print(user1.name)
print(user1.height)
print(user1.weight)
1
2
3
Kim
190
80

# 메소드 타입 (self / cls)

인스턴스 함수(메소드)

  • 인스턴스화 되었을 떄 접근/사용 가능
  • self를 인자로 받음

클래스 함수(메소드)

  • 클래스 안에 존재하기 때문에 공유 가능
  • cls를 인자로 받음
  • 메소드 위에 @classmethod 를 붙여서 사용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Person:
count = 0

def __init__(self):
# self.count 가 아니라 Person.count 접근
Person.count += 1


@classmethod
def call(cls):
# Person.count가 아니라 cls.count 접근
print('Class method all:', cls.count)

a = Person()
b = Person()
c = Person()

Person.call()

a, b, c 객체들이 인스턴스화 되면서 클래스 변수 count값을 각각 __init__() 에서 1씩 증가 시켰기 떄문에 출력해보면 3이 된다.

1
Class method all: 3

# get/set 속성값과 property

OOP 언어에서 private 속성을 위해 getter/setter 메소드 제공
파이썬에선 getter/setter 메소드 불필요
모든 속성과 메소드는 public 이며 필요에 따라서 property 사용가능

@property , @[데코레이터] 사용

@property : getter의 역할로 사용될 메소드 위에 데코레이터로 사용해준다. 변수로서의 사용을 가능하게 해준다.
@(getter역할의 메소드 이름).setter : getter역할의 메소드의 setter역할을 해주는 메소드위에 사용해준다. 변수로서의 사용을 가능하게 해준다.

⚠️ @property 와 @(getter역할의 메소드 이름).setter

  • getter와 setter역할을 하는 메소드의 이름은 동일하게 해주어야 한다.
  • @().setter의 ()에는 @property의 메소드 이름을 붙여준다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Person:
def __init__(self, name):
self.hidden_name = name

@property
def name(self):
return self.hidden_name

@name.setter
def name(self, name):
self.hidden_name = name

# 객체
p = Person('John')

@property를 데코레이터로 사용해주면 메소드를 변수처럼 사용할 수 있다.

1
print(p.name)
1
John

@name.setter의 메소드를 변수처럼 사용하여 hidden_name을 변경하는 setter를 실행시킨다.

1
2
p.name = 'Kevin'
print(p.name)
1
Kevin

@Property만 사용한 read-only

@property만 사용하고 setter를 사용하지 않으면, 외부에서 속성 변경이 불가한 read-only속성을 가진다.

1
2
3
4
5
6
7
8
9
10
11
12
13
class Circle:
def __init__(self, radius):
self.radius = radius

@property
def diameter(self):
return 2 * self.radius

circle = Circle(10)
print(circle.diameter)

circle.radius = 5
print(circle.diameter)
1
2
20
10

만약 속성을 변경하려 한다면, setter가 없기 때문에 에러가 발생한다.

1
circle.diameter = 100
1
2
3
4
5
6
7
8
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-24-17341e80dce9> in <module>()
14 print(circle.diameter)
15
---> 16 circle.diameter = 100

AttributeError: can't set attribute

# 네임 스페이스

인스턴스가 가지고 있는 자기 자신의 저장공간
인스턴스들의 네임스페이스들은 각자 독립적이다.
__dict__: 네임스페이스를 알수 있는 함수

1
2
3
4
5
6
7
8
9
10
11
12
class WareHouse:
# 클래스 변수
stock_num = 0
def __init__(self, name):
self.name = name
WareHouse.stock_num += 1
def __del__(self):
WareHouse.stock_num -= 1

user1 = WareHouse('Kim')
user2 = WareHouse('Pard')
user3 = WareHouse('Lee')

각 인스턴스들의 네임 스페이스를 출력 해보면

1
2
3
print(user1.__dict__)
print(user2.__dict__)
print(user3.__dict__)
1
2
3
{'name': 'Kim'}
{'name': 'Pard'}
{'name': 'Lee'}

클래스 변수: 직접 사용 가능, 객체 보다 먼저 생성, 공유 가능하다.

이때, 인스턴스들이 가지고 있지 않은 인스턴스 변수 외의 클래스 변수 값을 호출 할 수도 있다.

class변수인 stock_num은 user1, user2, user3 이 인스턴스화 되면서 각자의 초기화 함수를 통해 값이 3번 변하였다.

1
2
3
print(user1.stock_num)
print(user2.stock_num)
print(user3.stock_num)
1
2
3
3
3
3

인스턴스에 존재하지 않는 변수를 호출하면 인스턴스 네임 스페이스에서 찾고, 없으면 마지막으로 클래스 네임스페이스에서 찾아 호출한다.

# 객체(인스턴스) 삭제

1
del (객체(인스턴스))
Share