TIL08. Python : 객체 지향 프로그래밍(OOP)
📌 이 포스팅에서는 Python의 클래스에서 클래스 변수와 인스턴스 변수에 접근하는 방법과 매서드 실행에 관해 알아보겠습니다.
🌈 객체 지향 프로그래밍(OOP)
🔥 클래스 변수 VS 인스턴스 변수
🔥 매서드 실행과 self
1. 클래스 변수 VS 인스턴스 변수
🤔 클래스를 생성해 봅시다!
class Student(): """ Student Class Author : Jaewon """ # 클래스 변수 생성 student_count = 0 def __init__(self, name, number, grade, details, email=None): # 인스턴스 변수 : self가 항상 붙음 self._name = name self._number = number self._grade = grade self._details = details self._email = email # 클래스 변수 사용 : 클래스 변수에 접근할 때는 클래스 이름을 타고 들어감 Student.student_count += 1 # __str__ : 객체 출력할 경우, 반환 def __str__(self): return 'str {}'.format(self._name) # __repr__ : __str__과 유사한 기능이나, __str__보다 우선 순위 낮음 def __repr__(self): return 'repr {}'.format(self._name) # detail_info 메서드 : 객체의 id값 출력 def detail_info(self): print('Current ID : {}'.format(id(self))) print('Student Detail Info : {} {} {}'.format(self._name, self._email, self._details)) # __del__ : 오버라이딩으로 수정 def __del__(self): Student.student_count -= 1
🤔 ==
와 is
의 차이는 무엇일까?
✔️ 같은 값을 가진 2개의 객체 생성 후 id값을 확인하면, 서로 다른 것을 확인할 수 있습니다. 같은 속성값을 가진 객체라 해도 id값이 다르면 서로 다른 객체입니다.
✔️ 서로 다른 객체란 의미는 메모리에서 서로 다른 공간(=독립적 공간)에 저장되었다는 것을 의미합니다.
- print(id(student1)) ⇢ 140518341435344
- print(id(student2)) ⇢ 140518341435152
# 객체 생성 student1 = Student('Cho', 2, 3, {'gender':'M', 'score1':90, 'score2':44}) student2 = Student('Jang', 4, 3, {'gender':'F', 'score1':85, 'score2':74}, '[email protected]') # id 확인 print(id(student1)) # 140518341435344 print(id(student2)) # 140518341435152
✔️ "=="는 속성값(저장된 데이터) 비교하고, "is"는 id값(Reference Label)을 비교하여 True 또는 False를 반환합니다.
# '==' & 'is' 차이 : is는 reference된 주소 값을 비교하고, ==는 값을 비교함 print(student1 == student2) # False print(student1 is student2) # False print(student1._name == student2._name) # False 👈 ("cho" == "Jang"이기 때문) print(student1._grade == student2._grade) # True 👈 True (3 == 3이기 때문)
🤔 클래스 변수 및 인스턴스 변수 접근하는 방법
✔️ 클래스 변수는 클래스 내부에서 공용으로 사용되기 때문에 클래스명을 통해 접근 가능하며, 인스턴스명을 통해서도 접근 가능합니다.
- 클래스명으로 접근 : 🔍 [클래스명].[클래스변수명] ⇢ print(Student.student_count)
- 인스턴스로 접근 : 🔍 [인스턴스명].[클래스변수명] ⇢ print(student1.student_count)
✔️ 단, 인스턴스 변수는 인스턴스를 통해 접근 가능합니다.
- 🔍 인스턴스로 접근 : [인스턴스명].[인스턴스변수명] ⇢ print(student1._name) or print(student1._details)
# 클래스 변수 호출 : 클래스 변수인 "student_count"는 공용이기 때문에 자유롭게 접근 가능 print(Student.student_count) # 2 print(student1.student_count) # 2 print(student2.student_count) # 2
✔️ dir 메서드
: class 변수를 포함하여 사용 가능한 속성, 메서드 등을 리스트로 반환시켜줍니다.
print(dir(student1)) """ ['__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_details', '_email', '_grade', '_name', '_number', 'detail_info', 'student_count'] """
✔️ __dict__
내장 메서드는 네임스페이스(속성명과 속성값)를 딕셔너리 형태로 반환해줍니다.
✔️ 클래스를 통해 네임스페이스 확인하면, "student_count"가 존재하는데, 인스턴스를 통해 네임스페이스를 확인하면 네임스페이스에 "student_count"가 존재하지 않습니다. "student_count"가 인스턴스의 네임스페이스에 존재하지 않음에도 불구하고 인스턴스를 통해 클래스변수에 접근 가능한 이유는 접근하려는 변수가 인스턴스의 네임스페이스 없는 경우 클래스의 네임스페이스를 탐색하여 반환해주기 때문입니다.
print(Student.__dict__) # student_count가 존재 """ {'__module__': '__main__', '__doc__': '\n Student Class\n Author : Jaewon\n Date : 2021.05.07\n ', 'student_count': 2, '__init__': <function Student.__init__ at 0x7fb95c9275e0>, '__str__': <function Student.__str__ at 0x7fb95c927670>, '__repr__': <function Student.__repr__ at 0x7fb95c927700>, 'detail_info': <function Student.detail_info at 0x7fb95c927790>, '__del__': <function Student.__del__ at 0x7fb95c927820>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>} """ print(student1.__dict__) # student_count가 존재하지 않음 """ {'_name': 'Cho', '_number': 2, '_grade': 3, '_details': {'gender': 'M', 'score1': 90, 'score2': 44}, '_email': None} """
⭐️ python에서 인스턴스를 통해 변수에 접근할 때, 인스턴스의 네임스페이스에 없으면, 클래스가 갖고 있는지 확인하고, 그래도 없으면 부모 클래스까지 탐색하여 반환해줍니다.
⭐️ 아래에서 위로 올라가면서 찾아주는 bottom-up 방식이며, top-down으로는 탐색하지 않기 때문에 클래스의 네임스페이스에 없다고 인스턴스의 네임스페이스를 탐색하지 않습니다. 즉, 클래스를 통해 인스턴스의 네임스페이스에 접근하면 에러가 발생합니다.
2. 매서드 실행과 self
🤔 매서드의 실행은 어떻게 할까?
✔️ 클래스의 매서드는 인스턴스를 통해 접근 가능하고, 클래스를 통해서도 접근 가능합니다. 단, 클래스를 통해 메서드에 접근할 경우, 어떤 인스턴스인의 메서드를 요청하는지 파라미터를 명시해주어야 합니다.
- 인스턴스 통해 메서드 접근 : 🔍 [인스턴스명].[매서드명()]
- 클래스 통해 메서드 접근 : 🔍 [클래스명].[매서드명(인스턴스명)]
✔️ 클래스를 통해 메서드를 호출하였을 때, 파라미터를 주지않으면 어떤 인스턴스 대한 매서드인지 알지 못하기 때문에 에러가 발생합니다.
# 메서드 실행 student1.detail_info() student2.detail_info() # Student.detail_info() ## 👈 Error : self를 찾지 못하기 때문(인스턴스로 접근해야함!) Student.detail_info(student1) # 파라미터로 인스턴스를 넣어주면 가능(=student1.detail_info())
🤔 내장 매서드 doc
✔️ 내장 매서드 __doc__
는 주석을 반환시켜줍니다. 클래스 내부에 주석을 가지고 관련한 정보를 기록해두면 __doc__
를 통해 확인할 수 있습니다.
print(Student.__doc__) """ Student Class Author : Jaewon Date : 2021.06.24 """
🤔 내장 매서드 class
✔️ 내장 매서드 __class__
는 해당 인스턴스가 어떤 클래스에서 만들어졌는지 반환해줍니다.
print(student1.__class__, student2.__class__) # <class '__main__.Student'> <class '__main__.Student'> print(id(student1.__class__) == id(student2.__class__)) # True # True를 반환하는 이유는 Class(=Student)의 id를 비교했기 때문
Author And Source
이 문제에 관하여(TIL08. Python : 객체 지향 프로그래밍(OOP)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jewon119/TIL08.-Python-객체-지향-프로그래밍OOP저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)