콘텐츠로 건너뛰기

python Class

1. 시나리오

단계핵심 변화학습 포인트
1. 딕셔너리 리스트데이터 나열데이터가 많아질수록 관리가 힘들고 실수가 잦아짐을 깨달음
2. 생성 함수 (create_student)구조화 시작데이터의 형태(틀)를 일정하게 맞추는 법을 배움
3. 기능 함수 (총점, 평균, 표현)로직 분리데이터와 그 데이터를 처리하는 함수가 서로 연관되어 있음을 인지
4. 클래스 선언데이터 + 기능 결합흩어져 있던 데이터와 함수를 하나의 ‘객체’로 묶는 캡슐화를 이해

2. 딕셔너리 리스트

# object_1_basic.py

students=[
    {"name": "윤이성", "Korean": 87, "math":98, "english": 88, "science":99},
    {"name": "연하진", "Korean": 88, "math":99, "english":88, "science": 100}
     ]

print("이름", "총점", "평균", sep='\t')

for student in students:
    score_sum=student['Korean']+student['math']+student['english']+student['science']
    score_average=score_sum/4

    print(student['name'], score_sum, score_average, sep='\t')

# 키와 값을 깥이 써서 키 값을 계속 반복하는 문제점이 있다.
# students라는 학생들 객체가 있다는 것을 이해해야 한다.

-----------------------------

(.venv) robot@robot:~/Robot-AI$ /home/robot/Robot-AI/.venv/bin/python /home/robot/Robot-AI/Python/class/object_1_basic.py
이름    총점    평균
윤이성  372     93.0
연하진  375     93.75

3. 구조화 시작

# object_2_basic.py

def create_student(name, korean, math, english, science):
    return(
        {
        "name" : name,
        "Korean" : korean,
        "math" : math,
        "english" : english,
        "science" : science
        }
    )

students=[
    create_student("윤이성", 87, 98, 88, 99),
    create_student("연하진", 88, 99, 88, 100)
    ]

print("이름", "총점", "평균", sep='\t')

for student in students:
    score_sum=student['Korean']+student['math']+student['english']+student['science']
    score_average=score_sum/4

    print(student['name'], score_sum, score_average, sep='\t')

# 키와 값을 깥이 써서 키 값을 계속 반복하는 문제점이 있다.
# students라는 학생들 객체가 있다는 것을 이해해야 한다.

## 학생객체와 학생들 객체를 나눠서 생각하기 시작했다.
## 학생의 총점과 평균은 학생객체에 넣어서 생각해도 되지 않을까?

-----------------------------

(.venv) robot@robot:~/Robot-AI$ /home/robot/Robot-AI/.venv/bin/python /home/robot/Robot-AI/Python/class/object_2_basic.py
이름    총점    평균
윤이성  372     93.0
연하진  375     93.75

4. 기능별 분류

4.1 엉성한 기능별 함수

# object_3_basic.py

def create_student(name, korean, math, english, science):
    return(
        {
        "name" : name,
        "Korean" : korean,
        "math" : math,
        "english" : english,
        "science" : science
        }
    )

def score_sum():
    score_sum=student['Korean']+student['math']+student['english']+student['science']
    return score_sum

def score_average():
    score_average=score_sum()/4
    return score_average

def print_score():
    print(student['name'], score_sum(), score_average(), sep='\t')

students=[
    create_student("윤이성", 87, 98, 88, 99),
    create_student("연하진", 88, 99, 88, 100)
    ]

print("이름", "총점", "평균", sep='\t')

for student in students:
    print_score()


# 키와 값을 깥이 써서 키 값을 계속 반복하는 문제점이 있다.
# students라는 학생들 객체가 있다는 것을 이해해야 한다.

## 학생객체와 학생들 객체를 나눠서 생각하기 시작했다.
### 학생의 총점과 평균을 학생객체에 넣어서 생각하려고 했다.

### 출력도 학생객체가 담당하려고 했다.
### student라는 전역변수에 의존하고 있다.
### 그래서 함수와 객체와의 연결성이 보장되지 않는다.

-----------------------------

(.venv) robot@robot:~/Robot-AI$ /home/robot/Robot-AI/.venv/bin/python /home/robot/Robot-AI/Python/class/object_3_basic.py
이름    총점    평균
윤이성  372     93.0
연하진  375     93.75

  • 위 코드 문제점
    • student라는 전역변수에 의존하고 있다.
    • 그래서 함수와 객체와의 연결성이 보장되지 않는다.

4.2 덜 엉성한 기능별 함수

def create_student(name, korean, math, english, science):
    return(
        {
        "name" : name,
        "Korean" : korean,
        "math" : math,
        "english" : english,
        "science" : science
        }
    )

def score_sum(student):
    score_sum=student['Korean']+student['math']+student['english']+student['science']
    return score_sum

def score_average(student):
    score_average=score_sum(student)/4
    return score_average

def print_score(student):
    print(student['name'], score_sum(student), score_average(student), sep='\t')

students=[
    create_student("윤이성", 87, 98, 88, 99),
    create_student("연하진", 88, 99, 88, 100)
    ]

print("이름", "총점", "평균", sep='\t')

for student in students:
    print_score(student)


# 키와 값을 깥이 써서 키 값을 계속 반복하는 문제점이 있다.
# students라는 학생들 객체가 있다는 것을 이해해야 한다.

## 학생객체와 학생들 객체를 나눠서 생각하기 시작했다.
### 학생의 총점과 평균을 학생객체에 넣어서 생각하려고 했다.

### 출력도 학생객체가 담당하려고 했다.
### student라는 전역변수에 의존하고 있다.
### 그래서 함수와 객체와의 연결성이 보장되지 않는다.

#### 함수의 매개변수로 student 객체를 넣어서 연결했다.
#### 그런데 마지막 print_score의 리턴이 없다.
#### 출력 담당은 외부에서 처리하는 것일 좋다. 출력을 파일로도 웹으로도 보내야 하기 때문.

-----------------------------

(.venv) robot@robot:~/Robot-AI$ /home/robot/Robot-AI/.venv/bin/python /home/robot/Robot-AI/Python/class/object_4_basic.py
이름    총점    평균
윤이성  372     93.0
연하진  375     93.75

4.3 개선된 기능별 함수

def create_student(name, korean, math, english, science):
    return(
        {
        "name" : name,
        "Korean" : korean,
        "math" : math,
        "english" : english,
        "science" : science
        }
    )

def score_sum(student):
    score_sum=student['Korean']+student['math']+student['english']+student['science']
    return score_sum

def score_average(student):
    score_average=score_sum(student)/4
    return score_average

def student_info(student):
    return(f"{student['name']}\t{score_sum(student)}\t{score_average(student)}\t")

students=[
    create_student("윤이성", 87, 98, 88, 99),
    create_student("연하진", 88, 99, 88, 100)
    ]

print("이름", "총점", "평균", sep='\t')

for student in students:
    print(student_info(student))


# 키와 값을 깥이 써서 키 값을 계속 반복하는 문제점이 있다.
# students라는 학생들 객체가 있다는 것을 이해해야 한다.

## 학생객체와 학생들 객체를 나눠서 생각하기 시작했다.
## 학생의 총점과 평균을 학생객체에 넣어서 생각하려고 했다.

### 출력도 학생객체가 담당하려고 했다.
### student라는 전역변수에 의존하고 있다.
### 그래서 함수와 객체와의 연결성이 보장되지 않는다.

#### 함수의 매개변수로 student 객체를 넣어서 연결했다.
#### 그런데 마지막 print_score의 리턴이 없다.
#### 출력 담당은 외부에서 처리하는 것일 좋다. 출력을 파일로도 웹으로도 보내야 하기 때문.

##### 모든 것이 개선된 코드이다.

-----------------------------

(.venv) robot@robot:~/Robot-AI$ /home/robot/Robot-AI/.venv/bin/python /home/robot/Robot-AI/Python/class/object_5_basic.py
이름    총점    평균
윤이성  372     93.0
연하진  375     93.75

5. 클래스

지금까지의 과정을 요약하자면,

  1. 딕셔너리의 키를 계속 반복해서 집어 넣는것에서 해방. create_student()
  2. 기능별로 함수를 만들어서 코드 재사용. 단 전역변수 의존성 문제가 있음.
  3. 전역변수 의존성 문제를 매개 변수를 이용해서 해결.
  4. print_info 함수가 리턴 함수가 되도록 해서, 계산과 출력을 분리함.
  5. 그래서 최종, 각 기능별 함수를 매개변수를 이용해서 student 오브젝트와 연결되도록 함.

그런데, 각 기능별 함수를 보면, 이건 student라는 영역, 패밀리에 묶을 수 있다. 이러면 번거롭게 student라는 매개변수로 묶지 않아도 되지 않을까? 이런 생각이 클래스에 녹아있다.

즉, 아래와 같은 합의에 도착할 수 있다.

  1. 내가 학생이라는 객체를 만들어 내는 형태(변수와 함수들)를 모두 가지고 있다.
  2. 학생(student)이라는 객체를 만들 때, 나라는 클래스를 통해서 만들면 내 모든 변수와 함수들을 사용할 수 있게된다.
  3. 그래 그럼 나라는 클래스 이름은 Student라고 하고 자료형은 class라고 하자. class Student
  4. 그러면 student object는 Student라는 객체가 생성해서 주는것으로 하고 student=Student()로 하자.

이런 합의의 결과가 아래의 코드다.

# class_exterior.py

class Student:
    pass

student=Student() # 객체를 만들었다. 인스턴스라고 한다.

studnts=[ # 인스턴스 2 개를 만들어서 students 리스트에 넣었다.
    Student(),
    Student()
]

외형을 저렇게 만들어 놓았으니 이제 안쪽 인테리어를 마감할 차례다.

  1. 내가 만든 객체는 모두 이 범위(class)내에서는 self다. 이제 student를 매개변수로 쓰지 않고 self로 연결된다.
  2. 객체를 만들어주는 함수를 만들자. 생성자. def __init__(self, arg*): 함수로 만든다.
  3. 객체를 삭제하는 함수도 있다. 소멸자. def __del__(self):
  4. 이 객체 내에 선언되는 변수는 self.variables로 연결된다.
  5. 이 객체 내에서 선언되는 함수(메소드) 모드 function(self, arg*) 형태로 구성된다.

그러므로 아래처럼 class 정의부를 선언할 수 있다.

# class_interor.py

class Student:
    def __init__(self, name, korean, math, english, science): #생성자
        self.name=name
        self.Korean=korean
        self.math=math
        self.english=english
        self.science=science

    def score_sum(self):
        return self.Korean+self.math+self.english+self.science

    def score_average(self):
        return self.score_sum()/4

    def student_info(self):
        return f"{self.name}\t{self.score_sum()}\t{self.score_average()}"

class 내부에서 정의되는 함수가 다른 내부 함수를 콜 할 때는 self.funciton(self)로 호출하면 안되는 것만 주의하면 쉽게 위와 같은 형태를 만들 수 있을 것이다.

아래는 최종 class 파일이다.

# classs_student.py

class Student:
    def __init__(self, name, korean, math, english, science): #생성자
        self.name=name
        self.Korean=korean
        self.math=math
        self.english=english
        self.science=science

    def score_sum(self):
        return self.Korean+self.math+self.english+self.science

    def score_average(self):
        return self.score_sum()/4

    def student_info(self):
        return f"{self.name}\t{self.score_sum()}\t{self.score_average()}"

students = [
    Student("윤이성", 87, 98, 88, 99),
    Student("연하진", 88, 99, 88, 100)
]

for student in students:
    print(student.student_info())

-----------------------------

(.venv) robot@robot:~/Robot-AI$ /home/robot/Robot-AI/.venv/bin/python /home/robot/Robot-AI/Python/class/class_student.py
윤이성  372     93.0
연하진  375     93.75

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다