goodthings4me.tistory.com
■ 클래스의 인스턴스(객체)별로 존재하는 변수를 인스턴스 변수라고 하며, 인스턴스(객체)에 속하지 않고 클래스에 속한 변수를 클래스 변수라고 한다.
class Simple:
cv = 20 # 클래스 변수
def __init__(self):
self.iv = 10 # 인스턴스 변수, 객체별로 존재
s = Simple()
print(s.iv) # 10 / 인스턴스 변수는 객체를 통해 접근함
#print(Simple.iv) # AttributeError: type object 'Simple' has no attribute 'iv'
# 클래스 변수는 클래스 이름으로 접근 가능
print(Simple.cv) # 20
# 객체를 통해서도 클래스 변수에 접근 가능
print(s.cv) # 20
# 접근하는 변수가 객체에 없으면 그 객체의 클래스에 가서 변수를 찾기 때문에 객체를 통해서도 접근이 가능하나, 가급적 클래스 변수는 클래스 이름을 통해 접근을 권장함
# 클래스 변수는 객체들이 사용한 공용 변수이다.
class Simple:
count = 0 # Simple 클래스 변수, 생성된 객체의 수를 저장하는 변수
def __init__(self):
Simple.count += 1
def get_count(self):
return Simple.count
def main():
s1 = Simple()
print(s1.get_count()) # 1
s2 = Simple()
print(s2.get_count()) # 2
s3 = Simple()
print(s3.get_count()) # 3
# 하나의 클래스 변수를 3개의 객체로 접근(어떤 객체로든지 접근 가능함)
print(s1.get_count()) # 3
# 클래스명으로 get_count() 접근 불가 --> 인자로 객체를 전달하면 가능
print(Simple.get_count(s1)) # 3
main()
■ 스태틱(static) 메서드와 클래스 메서드
- 파이썬의 클래스에서 직접 접근할 수 있는 메서드로 staticmethod와 classmethod가 있다.
- 파이썬에서는 타 언어와 달리 인스턴스(객체)에서도 staticmethod에 접근 가능하고, 스태틱 메서드는 객체별로 공유하는 메서드이다.
- 인스턴스(객체) 메소드는 첫번째 인자로 객체 자신(self)을 입력하지만, classmethod는 클래스 자신(cls)을 입력하고, staticmethod는 인자가 없다.
# 스태틱 메서드(staticmethod)
위 코드에서 생성된 객체수를 확인하기 위해 get_count()를 만들었는데, 이는 객체를 생성한 후 생성된 객체를 통해 접근하고 있다. 객체를 생성하지 않고도 몇 개의 객체가 생성되었는지 확인 가능한 메서드가 스태틱메서드다.
class Simple:
count = 0
def __init__(self):
Simple.count += 1
def sm_get_count(): # 첫 인자로 self가 없는 메서드 (static 메서드)
print('static method!!')
return Simple.count
sm_get_count = staticmethod(sm_get_count) # 스태틱 메서드로 만드는 방법
def main():
print(Simple.sm_get_count()) # 0
# 스태틱메서드는 객체가 없는 상태에서도 객체의 현재 수를 구할 수 있다.
s1 = Simple()
s2 = Simple()
s3 = Simple()
s4 = Simple()
print(Simple.sm_get_count()) # static method!!, 4
print(s1.sm_get_count()) # static method!!, 4
# 스태틱 메서드는 클래스명 또는 객체로도 접근(호출) 가능
main()
스태틱 메서드에 self가 없는 것은 그 메서드가 객체에 속하는 것이 아니라 클래스에 속한 메서드이기 떄문이다.
위 코드에서 스태틱 메서드로 만드는 sm_count = staticmethod(sm_count) 대신에 아래처럼 데코레이터 방법(@staticmethod)을 많이 사용한다.
@staticmethod
def sm_get_count(): # 첫 인자로 self가 없는 메서드 (static 메서드)
print('static method!!')
return Simple.count
# 클래스 메서드(classmethod)
- 스태틱 메서드를 만드는 데코레이터처럼 클래스 메서드도 데코레이터로 만든다.
- 스태틱 메서드와 클래스 메서드의 외형적 차이는 첫번쨰 인자인 'cls'의 유무이다. ('cls' 말고 다른 단어로 해도 되지만, 관용적으로 사용하니 그냥 ~ ~)
- 클래스 메서드의 호출 시 cls에 인자를 전달하지 않는다.
class Simple:
num = 5 # 클래스 변수
@staticmethod
def sm(i):
print('static : 5 + {0} = {1}'.format(i, Simple.num + i))
@classmethod
def cm(cls, i): # 클래스 메서드
print('class :5 + {0} = {1}'.format(i, Simple.num + i))
def main():
Simple.sm(3) # static : 5 + 3 = 8
Simple.cm(3) # class :5 + 3 = 8
s = Simple()
s.sm(4) # static : 5 + 4 = 9
s.cm(4) # class :5 + 4 = 9
main()
클래스 메서드의 cls에 자동으로 전달되는 것은 그 메서드를 가진 클래스 자신이다.(파이썬은 클래스도 객체이기 때문에 인자로 전달 및 반환이 가능함)
class Simple:
count = 0
def __init__(self):
Simple.count += 1
@classmethod
def get_count(cls):
return cls.count # cls에 전달되는 것은 Simple 클래스. ==Simple.count
def main():
print(Simple.get_count()) # 0
s = Simple()
print(Simple.get_count()) # 1
main()
※ cls에 전달되는 것이 클래스이므로 이를 기반으로 객체를 생성할 수 있다.
class Natural:
def __init__(self, n):
self.n = n
def get_n(self):
return self.n
@classmethod
def add(cls, n1, n2):
return cls(n1.get_n() + n2.get_n()) # ==Natural(n) 객체 생성 후 반환
def main():
n1 = Natural(10)
n2 = Natural(20)
n3 = Natural.add(n1, n2) # 클래스메서드 호출, 반환되는 객체를 n3에 저장
print('{0} + {1} = {2}'.format(n1.get_n(), n2.get_n(), n3.get_n()))
main()
[클래스메서드 사용 예]
class Date: # 날짜 표현 클래스
def __init__(self, y, m, d):
self.year = y
self.month = m
self.day = d
def show(self):
print('{0}. {1}. {2}'.format(self.year, self.month, self.day))
@classmethod
def next_day(cls, today):
return cls(today.year, today.month, today.day + 1)
def main():
d1 = Date(2020, 4, 5)
d1.show() # 2020. 4. 5
d2 = Date.next_day(d1)
# cls(y, m, d) == Date(y, m, d) / 객체를 생성 후 반환
d2.show() # 2020. 4. 6
main()
[classmethod와 staticmethod 의 차이]
class Animal:
language = '울음소리'
def __init__(self):
self.sound = '동물 울음소리 : ' + self.language
@classmethod
def cls_language(cls):
return cls()
@staticmethod
def stc_language():
return Animal()
def show(self):
print(self.sound)
class Dog(Animal):
language = '멍멍'
a = Animal.cls_language()
b = Animal.stc_language()
print(a.show()) # 동물 울음소리 : 울음소리 / 부모클래스의 속성 값
print(b.show()) # 동물 울음소리 : 울음소리 / 부모클래스의 속성 값
c = Dog.cls_language()
d = Dog.stc_language()
print(c.show()) # 동물 울음소리 : 멍멍 / cls 클래스의 속성 값
print(d.show()) # 동물 울음소리 : 울음소리 / 부모클래스의 속성 값
[참고 자료] 윤성우의 열혈파이썬 중급편
'코딩 연습 > 코딩배우기' 카테고리의 다른 글
[python] 파이썬의 변수, 객체, 그리고 참조 주소 (0) | 2020.09.19 |
---|---|
[python] 파이썬의 진수 변환(2진수, 8진수, 10진수, 16진수) (0) | 2020.09.18 |
[python] 파이썬 데코레이터 (Decorator) (0) | 2020.09.16 |
[python] 파이썬 중첩함수(Nested Function)와 클로저(Closure) (0) | 2020.09.15 |
[python] 파이썬 property객체, @property 데코레이터 (0) | 2020.09.14 |
댓글