1. 클래스(Class)
클래스는 데이터와 데이터를 조작하는 함수를 하나의 묶음으로 관리하는 방법을 제공한다.
새 클래스를 만드는 것은 객체의 새로운 형을 만들어서, 그 형의 새 인스턴스를 만들 수 있도록 한다.
각 클래스 인스턴스는 상태를 유지하기 위해 자기 자신에게 첨부된 속성(attribute)를 가질 수 있다.
클래스를 정의하려면 class 키워드를 사용한다.
class MyClass:
class_attr = "I am a class attribute" #class_attr은 클래스 attribute
obj1 = MyClass() # obj1은 인스턴스
1.1 __init__ 메소드
__init__ 메소드는 클래스의 인스턴스가 생성될 때 자동으로 호출되는 메소드로 생성자 메소드라고도 불린다.
__init__ 메소드는 인스턴스 속성을 초기화하는데 사용된다.
1.2 self 키워드
self는 클래스 내에서 인스턴스 변수를 나타내는 특별한 키워드이다.
1.2.1 인스턴스 메소드의 첫 번째 매개변수
클래스의 인스턴스 메소드는 첫 번째 매개변수로 self를 사용하는 것이 일반적이다. (self 대신 다른 단어를 사용해도 동작은 한다.)
아래 예제에서 print_method는 인스턴스가 호출된 p1을 self로 참조한다.
1.2.2 인스턴스 attribute 접근
self를 통해 클래스 내부에서 인스턴스 변수를 정의하고 접근할 수 있다.
class Person:
def __init__(self, name):
self.name = name #self.name과 self.nation은 인스턴스 attribute
self.nation = "korean"
def print_method(self):
print(self.name, self.nation)
# Person 인스턴스 생성
p1 = Person("kim")
p1.print_method() # 출력 : kim korean
1.2.3 다른 인스턴스 메소드 호출
self를 사용하면 클래스 내에서 다른 인스턴스 메소드를 호출할 수 있다.
class MyClass:
def method1(self):
return "method1 called"
def method2(self):
return self.method1() + " and method2 called"
# MyClass 인스턴스 생성
obj = MyClass()
print(obj.method2()) # 출력: method1 called and method2 called
2. 속성(Attribute)
속성은 클래스 내부에 포함되어 있는 메소드나 변수를 의미한다.
파이썬에서 속성은 크게 클래스 속성과 인스턴스 속성으로 나뉜다.
2.1 클래스 Attribute
- 클래스 attribute는 클래스 자체에 정의된다.
- 모든 인스턴스가 동일한 값을 공유한다.
- (예제1) 클래스 attribute는 클래스 정의 시점에 생성되며, 클래스의 모든 인스턴스와 독립적으로 존재한다.
- (예제1) 클래스 attribute는 클래스 자체에 속하기 때문에, 클래스 이름을 통해 접근할 수 있다. (객체를 생성하지 않아도 클래스 attribute에 접근할 수 있다.)
- (예제3) 인스턴스를 통해 접근할 수 있지만, 인스턴스에 의해 변경되지 않는다.
즉 인스턴스를 통해 변경된 attribute값은 해당 인스턴스에만 적용이 되고 클래스 attribute값은 변경이 되지 않는다.
-> 확인하는 코드는 접은 글에서 추가적으로 확인 가능하다.
class MyClass:
class_attr = "I am a class attribute"
# 클래스 attribute에 인스턴스 생성 없이 직접 접근
print("----- 1. -----")
print(MyClass.class_attr) # 출력 : I am a class attribute
# 인스턴스를 통해 클래스 attribute에 접근
print("\n----- 2. -----")
obj1 = MyClass()
obj2 = MyClass()
print(obj1.class_attr) # 출력: I am a class attribute
print(obj2.class_attr) # 출력: I am a class attribute
# 인스턴스를 통해 클래스 attribute 값 변경
print("\n----- 3. -----")
obj1.class_attr = "edited"
print(obj1.class_attr) # 출력: edited
print(obj2.class_attr) # 출력: I am a class attribute
# 클래스 attribute 변경
print("\n----- 4. -----")
MyClass.class_attr = "Changed class attribute"
print(obj1.class_attr) # 출력: Changed class attribute
print(obj2.class_attr) # 출력: Changed class attribute
2.2 인스턴스 attribute
- 인스턴스 attribute는 클래스의 각 인스턴스에 속하는 변수이다.
- 각 인스턴스는 자체적인 인스턴스 attribute를 가지며, 이는 다른 인스턴스와 독립적이다.
- 일반적으로 클래스의 __init__ 메소드 내에서 정의된다.
- 인스턴스 이름을 통해 접근할 수 있다.
class MyClass:
def __init__(self, value):
# 인스턴스 attribute
self.instance_attr = value
# 인스턴스 attribute에 접근
obj1 = MyClass(1)
obj2 = MyClass(2)
print(obj1.instance_attr) # 출력: 1
print(obj2.instance_attr) # 출력: 2
# 인스턴스 attribute 변경
obj1.instance_attr = 3
print(obj1.instance_attr) # 출력: 3
print(obj2.instance_attr) # 출력: 2
특성 | 클래스 Attribute | 인스턴스 Attribute |
정의 위치 | 클래스 본문 내에서 정의 | 일반적으로 __init__ 메소드 내에서 정의 |
접근 방법 | 클래스 이름이나 인스턴스를 통해 접근 | 인스턴스를 통해 접근 |
값의 공유 | 모든 인스턴스가 값을 공유 | 각 인스턴스는 독립적인 값을 가짐 |
변경 시 영향 범위 | 클래스 전체에 영향 | 해당 인스턴스에만 영향 |
a. 인스턴스를 통해 클래스 attribute를 변경하는 내용에 대한 추가 코드 설명
2.1 클래스 attribute에서 인스턴스를 통해 클래스 attribute에 접근할 수 있지만, 클래스 attribute 값을 변경할 수 없다고 했다.
위에서 사용한 코드로 보다 상세하게 살펴보자.
아래 예제에서 obj1.class_attr = "edited" 실행함으로써 obj1 인스턴스를 통해 클래스 attribute 값을 변경하고자 했다.
그 결과 obj1.class_attr를 출력해보면 "edited"가 출력되지만, obj2.class_attr는 "I am a class attribute"가 출력된다.
class MyClass:
class_attr = "I am a class attribute"
obj1 = MyClass()
obj2 = MyClass()
# 인스턴스를 통해 클래스 attribute 값 변경
print("\n----- 3. -----")
obj1.class_attr = "edited"
print(obj1.class_attr) # 출력: edited
print(obj2.class_attr) # 출력: I am a class attribute
그 이유는 obj1.class_attr = "edited"를 실행하면 obj1은 인스턴스 네임스페이스에 class_attr라는 이름의 새로운 attribute를 추가한 후, 클래스 attribute를 덮어쓰기 때문이다. 이렇게 생성된 attribute는 인스턴스 attribute로 obj1에서만 접근 가능하다.
다른 인스턴스(obj2)는 여전히 클래스 attribute를 참조한다.
아래 코드를 통해 확인ㅎ
# obj1 인스턴스 네임스페이스 확인
print(obj1.__dict__) # 출력: {'class_attr': 'edited'}
# obj2 인스턴스 네임스페이스 확인
print(obj2.__dict__) # 출력: {}
# MyClass 클래스 네임스페이스 확인
print(MyClass.__dict__)
# class_attr는 여전히 클래스 attribute로 존재
# 출력 : {'__module__': '__main__', 'class_attr': 'I am a class attribute', '__dict__': <attribute '__dict__' of 'MyClass' objects>, '__weakref__': <attribute '__weakref__' of 'MyClass' objects>, '__doc__': None}
obj1.__dict__는 인스턴스 attribute를 포함하며 {'class_attr' : 'edited}를 출력한다.
obj2.__dict__는 비어있다.
Myclass.__dict__ 는 여전히 class_attr가 클래스 attribute로 존재한다.
정리하자면 인스턴스를 통해 클래스 attribute를 변경하면, 해당 인스턴스에서 새로운 인스턴스 attribute가 생성되고 클래스 attribute를 덮어쓰게 된다. 이 인스턴스 attribute는 다른 인스턴스에 영향을 미치지 않는다.
'회고' 카테고리의 다른 글
[24.06.04] 99클럽 코테 스터디 16일차 TIL - 그리디 알고리즘 (0) | 2024.06.04 |
---|---|
[24.06.03] 99클럽 코테 스터디 15일차 TIL - 인스턴스 메소드, 클래스 메소드, 정적 메소드 (0) | 2024.06.03 |
[24.06.01] 99클럽 코테 스터디 13일차 TIL - OrderedDict (0) | 2024.06.01 |
[24.05.31] 99클럽 코테 스터디 12일차 TIL - DefaultDict (0) | 2024.05.31 |
[24.05.30] 99클럽 코테 스터디 11일차 TIL - 회전 알고리즘, 튜플 자료형 (0) | 2024.05.30 |