시작일로부터 몇일이 지났는지는 현재 시간에서 시작 시간을 빼서 일수로 전환하여 계산하였다.
if end :
# FORMAT STRING TO DATE
start_day = datetime.datetime.strptime(self.end, "%Y%m%d")
end_day = datetime.datetime.strptime(self.start, "%Y%m%d")
day_sum = (start_day-end_day).days
# INITIALIZE ACHIEVEMENT
self.achievement = (self.dayCount/day_sum)*100
또한 달성도에 대해서는 시작시간에서 끝나는 시간을 빼서 총 소요되는 일수를 구하고,
현재 시간에서 총 일수를 나눈 뒤 100을 곱해서 퍼센트화 시켰다.
datetime 모듈에 대해서 익숙해진다면 크게 어렵지 않는 활용법이라 생각한다.
2. 시간의 경과에 따른 데이터의 갱신
시간은 고정된 것이 아니라 계속 흐르기 때문에 그에 따른 데이터의 갱신이 필요하다.
따라서 경과 시간(dayCount)와 달성도(achievement)를 갱신하는 함수가 필요하다.
def update(self):
# UPDATE ACHIEVEMENT, DAY COUNT
self.dayCount = (datetime.datetime.now() - datetime.datetime.strptime(self.start, "%Y%m%d")).days
if self.end :
# FORMAT STRING TO DATE
start_day = datetime.datetime.strptime(self.end, "%Y%m%d")
end_day = datetime.datetime.strptime(self.start, "%Y%m%d")
day_sum = (start_day-end_day).days
# INITIALIZE ACHIEVEMENT
self.achievement = (self.dayCount/day_sum)*100
1. test 인스턴스인 s와 t를 생성하고 이의 인스턴스 변수인 이름을 s와 t로 정한다.
인스턴스를 생성하는 순간 클래스 변수인 all_var를 1씩 증가시킨다.
2. 이후 __show__ 함수를 통하여 all_var의 값과 각 인스턴스 변수인 name을 출력한다.
3. 다음으로는 클래스 내에 test 함수를 통하여 각 인스턴스의 all_var 값을 4로 변경시킨다.
4. 각 인스턴스 변수의 all_var와 클래스 변수의 all_var 값을 출력한다.
이 과정에 대한 출력은 다음과 같다.
코드 실행 결과
먼저 두개의 인스턴스가 생성된 뒤 출력이 이루어지는데, 조금 특이한 것이 있다.
print('all_var : ', test.all_var)
하나는 각 인스턴스가 all_var를 가지고 있는 것이 아니라 클래스 변수 all_var를 직접 출력하는 것이고
두번째는 각 인스턴스가 공유하는 클래스 변수가 동일하다는 것이다.
즉 위와 같이 형성이 된다는 의미다.
s와 t는 각자의 인스턴스지만 test라는 클래스의 all_var라는 변수는 공유하는 셈이 된다.
그렇다면 s와 t의 all_var를 self연산자를 통하여 수정하면 어떻게 될까라는 생각이 들고,
위의 결과와 같이 4, 4, 2가 출력 된 것을 볼 수 있다.
그 의미는 다음과 같은 그림이 된다고 볼 수 있다.
클래스 변수인 all_var는 여전히 존재하고, 각 인스턴스에 클래스 변수인 all_var가 각각 할당 되었다는 말이다.
물론 이 이후에 다시 __show__() 함수를 사용한다 해도 all_var의 값은 4가 출력되는 것이 아니라 클래스 변수의 값인 2가 출력된다.
다만 s.all_var, t.all_var로 접근이 가능해진다는 점이 추가된다.
최종적으로 실험한 코드는 이와 같다.
class test:
all_var = 0
# name을 받아서 이름으로 초기화 하면서 인스턴스를 생성
def __init__(self, name):
test.all_var += 1
self.name = name
# 클래스 변수 all_var를 출력, 인스턴스의 이름을 출력
def __show__(self):
print('all_var : ', test.all_var)
print('name : ', self.name)
# 각 인스턴스의 all_var를 4로 초기화 하고 인스턴스의 all_var를 출력
def test(self):
self.all_var = 4
print(self.all_var)
#s, t 두개의 test 인스턴스 생성
s = test('s')
t = test('t')
# 이름과 all_var를 출력한다
# 여기서 all_var는 클래스 멤버를 출력
s.__show__()
t.__show__()
# 인스턴스의 all_var를 출력해도 클래스 멤버가 출력된다.
# 이는 인스턴스의 네임스페이스에 존재하지 않기때문에 class로 올라가게 된다.
print(s.all_var ,'변경이전 allvar')
# 각 인스턴스에 all_var를 초기화 시킨다.
# 이후 출력시킨다.
# 각 인스턴스와 클래스의 all_var가 다름을 확인
print('modify instance all_var.')
s.test()
t.test()
print(test.all_var)
# 이후 인스턴스에서 all_var에 접근하면 인스턴스의 all_var에 접근하는 것을 확인
print(s.all_var ,' 추가됨 ')
3. 정리
1. 파이썬의 클래스는 클래스 멤버와 인스턴스 멤버가 존재한다
2. 인스턴스들의 멤버는 굳이 각자가 클래스 멤버를 초기화 하지 않는 이상 클래스 멤버를 공유한다.
3. 2번의 사실로 인하여 각 인스턴스가 공유해야하는 값이 존재할 때는 클래스 멤버,
그렇지 않을 경우 인스턴스 멤버로 초기화 하면 된다.
3번의 예시)
학교의 출석 시스템에서, 각 학생들에 대한 정보는 인스턴스 정보로 저장해야하나
전체적인 학생 수와 같이 모두 동일하게 적용되야 하는 경우는 클래스 멤버로 적용한다.
구현 예 )
100명이 다니는 학교에 학생 A, B, C가 있을 때, 각 등수는 2, 30, 66일 때 성적 상위 백분위를 구하자고 하면,
등수/전체 학생수의 방식으로 구하기 때문에 전체 학생수(클래스 멤버) 와 등수(인스턴스 멤버)를 활용하여 구할 수 있다.