[Python] 클래스(Class) - 클래스 정의, 정보 저장, 값 변경, 객체 리스트

2023. 2. 5. 00:46파이썬(Python)

반응형

1. 클래스(Class)란?

- 새로운 형태를 하나 정의한 후, 형태를 이루기 위한 요소로 새로운 값을 정의하는 것.

- 예를 들어, 두 학생의 국어, 수학, 영어 점수가 각각 (50, 60, 70), (70, 80, 90)이라 하자.

kor1, math1, eng1=50,60,70
kor2, math2, eng2=70,80,90

 

- 이와 같이 변수를 직접 정의하여 사용할 수도 있지만, (국어, 수학, 영어)처럼 3개의 세트가 한 학생에 대한 정보를 나타내는 것이 효율적이고 직관적이다.

- 따라서 학생을 가리키는 새로운 형태를 하나 정의하고 그 형태를 이루기 위한 요소로 (국어, 수학, 영어)를 정의해야 하는데 이때, 사용하는 것이 클래스이다.

 

● 클래스 정의

class Student:
    def __init__(self,kor,math,eng):
        self.kor=kor
        self.math=math
        self.eng=eng

 

- __init__은 Student 클래스의 형태를 정의하는 생성자(constructor)이다.

- self는 Student 클래스에서 학생을 가리키고, 항상 첫 번째 인자로 넣어준다.

- kor, math, eng는 멤버 변수이며, 인자로 넘어오는 kor, math, eng는 학생의 국어, 수학, 영어 점수가 되어야 한다.

 

● 클래스를 이용하여 정보를 저장

class Student:
    def __init__(self,kor,math,eng):
        self.kor=kor
        self.math=math
        self.eng=eng

student1=Student(50,60,70)
print(student1.kor)
print(student1.math)
print(student1.eng)

 

결과

50
60
70

 

- Student를 함수 호출할 때처럼 사용하여, __init__에 self 다음에 인자가 정의되어 있는 순서대로 값을 입력한다.

- 각각의 값을 갖는 하나의 학생 객체(instance)를 만든다. 여기서는 student1 객체를 만들었다.

- student1은 kor, math, eng멤버 변수를 갖는다.

- "객체이름.멤버변수" 형태로 사용이 가능하다. (student1의 영어 성적 : student1.eng)

- 이처럼 class를 선언하고 class를 이용하여 객체를 만들면 값을 관리할 수 있다.

 

class Student:
    def __init__(self,kor,math,eng):
        self.grade1=kor
        self.grade2=math
        self.grade3=eng

student1=Student(50,60,70)
print(student1.grade1)
print(student1.grade2)
print(student1.grade3)

- 멤버 변수의 이름을 grade1, grade2, grade3로 정의했다면, 객체 생성 후 이름을 grade1, grade2, grade3로 사용한다.

 


2. 클래스를 통한 값 변경

class Student:
    def __init__(self,kor,math,eng):
        self.grade1=kor
        self.grade2=math
        self.grade3=eng

student=Student()

 

결과

Student.__init__() missing 3 required positional arguments: 'kor', 'math', and 'eng'

 

- 위와 같이 객체를 생성 시 국어, 수학, 영어 점수가 주어지지 않으면 에러가 발생한다.

- 각 인자에 값이 넘어오지 않을 때 어떤 값을 취하게 할 것 인지 설정해 주면 해결할 수 있다.

 

class Student:
    def __init__(self,kor=0,math=0,eng=0):
        self.grade1=kor
        self.grade2=math
        self.grade3=eng

student=Student()
print(student.grade1)
print(student.grade2)
print(student.grade3)

 

결과

0
0
0

 

- 객체에 이미 들어있는 값은 '객체이름.멤버변수 = 바꿀 값' 형태로 값을 변경한다.

 

class Student:
    def __init__(self,kor=0,math=0,eng=0):
        self.grade1=kor
        self.grade2=math
        self.grade3=eng

student=Student()
print(student.grade1)
print(student.grade2)
print(student.grade3)

student.grade1=70
student.grade2=80
student.grade3=90

print(student.grade1)
print(student.grade2)
print(student.grade3)

 

결과

0
0
0
70
80
90

 


3. 클래스를 이용한 객체 리스트

● 국어, 수학, 영어 점수를 포함한 학생 3명의 정보를 표현하기

class Student:
    def __init__(self,kor=0,math=0,eng=0):
        self.kor=kor
        self.math=math
        self.eng=eng

students=[Student(50,60,70), Student(60,70,80), Student(70,80,90)]

student2=students[1]  # 2번째 학생
print(student2.kor, student2.math, student2.eng)  # 2번째 학생의 점수

 

결과

60 70 80

 

- 3명의 학생 점수를 입력받아 리스트를 만드는 경우

class Student:
    def __init__(self,kor=0,math=0,eng=0):
        self.kor=kor
        self.math=math
        self.eng=eng

students=[]
for _ in range(3):
    kor,math,eng=map(int,input().split())
    students.append(Student(kor,math,eng))

print(students[1].kor,students[1].math,students[1].eng) # 2번째 학생 점수

 

결과

>> 10 20 30
>> 50 60 70
>> 40 30 50
50 60 70

 


Q) 게임 이용자 정보 정리

- 자연수 n을 입력

- n명의 게임 정보인 아이디레벨을 입력한다. (아이디는 영어로만 입력한다.)

- 운영자와 n명의 이용자들의 정보를 출력한다. (운영자 정보를 먼저 출력 후, 이용자들의 정보를 출력)

- 운영자의 아이디는 GameManager, 레벨은 100이다. (변수 초기화 사용)

- 출력 형태는 "id : GameManager, level : 100"으로 한다.

- 레벨이 가장 높은 이용자의 아이디를 출력한다. (운영자 포함)

- 아이디가 사전순으로 가장 나중에 오는 아이디와 레벨을 출력하라. (운영자 포함)

 

class User:
    def __init__(self,id="GameManager",level=100):
        self.id=id
        self.level=level

n=int(input())
users=[User()]
for _ in range(n):
    id,level=input().split()
    level=int(level)
    users.append(User(id,level))

max_level_idx=0
name_idx=0

for i in range(n+1):
    print(f'id : {users[i].id}, level : {users[i].level}')
    if users[i].level>users[max_level_idx].level:
        max_level_idx=i
    
    if users[i].id>users[name_idx].id:
        name_idx=i


print(f'가장 높은 레벨의 아이디는 {users[max_level_idx].id}')
print(f'사전순으로 가장 나중에 오는 아이디는 {users[name_idx].id} 레벨은 {users[name_idx].level}')

 

결과

>> 5
>> apple 99
>> samsung 150
>> kakao 77
>> google 30
>> tesla 50
id : GameManager, level : 100
id : apple, level : 99
id : samsung, level : 150
id : kakao, level : 77
id : google, level : 30
id : tesla, level : 50
가장 높은 레벨의 아이디는 samsung
사전순으로 가장 나중에 오는 아이디는 tesla 레벨은 50

 

해설)

- 운영자 정보초기값이고 제일 먼저 출력해야 하기 때문에 인자가 없는 클래스를 유저의 정보 리스트 users에 삽입.

- 운영자를 포함한 n명의 이용자들의 아이디와 레벨을 출력

- 동시에 최고 레벨사전순으로 가장 늦게 오는 이름의 index를 갱신

 


Q) 비 오는 날

- 자연수 n을 입력

- n개의 데이터를 입력. 데이터는 날짜(yyyy-mm-dd), 요일(Sun, Mon, Tue, Wed, Thu, Fri, Sat), 날씨 (sun, cloudy, rain, snow)

- 가장 최근에 비가 온 날짜와 요일을 출력.

- 연도는 2000 ~ 2100 사이이며, 오늘을 2000-01-01이라 가정한다.

 

class WeatherData:
    def __init__(self,date, day, weather):
        self.date=date
        self.day=day
        self.weather=weather
    
n=int(input())
arr=[input().split() for _ in range(n)]
datas=[WeatherData(date,day,weather) for date,day,weather in arr]

rain_date,rain_day='2100-12-31',''
for i in range(n):
    if datas[i].weather=='rain':
        if datas[i].date<rain_date:
            rain_date, rain_day=datas[i].date, datas[i].day

print(f'가장 최근에 비가 오는 날은 {rain_date} {rain_day}')

 

결과

>> 5
>> 2051-06-04 Mon rain
>> 2034-09-14 Fri sun
>> 2078-10-23 Sat cloudy
>> 2025-03-19 Thu rain
>> 2008-02-02 Tue snow
가장 최근에 비가 오는 날은 2025-03-19 Thu

 

해설)

- n개의 정보들을 입력할 때 list_comprehension을 이용했다.

- 비가 오는 날짜와 요일을 초기값을 각각 '2100-12-31', ' '으로 설정했다.

- 가장 최근에 비가 오는 날을 구해야 하기 때문에 입력할 수 있는 가장 늦은 날짜를 초기값으로 설정한다.

- 요일은 중요하지 않기 때문에 공백으로 남겨두었다.

- 날씨가 rain이면서 날짜가 rain_date보다 작으면 rain_daterain_day를 갱신한다.

- 객체의 날짜와 rain_date는 string형식이므로 앞 글자를 비교하여 아스키코드가 더 작은 값사전순으로 앞선 문자열을 의미한다.

- 여기서는 날짜이므로 사전순으로 앞선 문자열이 앞선 날짜임을 의미한다.

- 즉, 최근에 비가 온 날은 비가 온 날들 중 연도가 가장 최소일 때, 연도가 같으면 월이 최소, 연도와 월이 같으면 일이 최소인 날이 된다.