본문 바로가기

Python/basic

[Python] class를 활용하여 영화 목록 관리하기

첫번째 글에서 여러가지 함수를 정의하고 dictionary를 활용해 영화 목록을 만들어봤다.

이번에는 더 간단하게 class를 활용해보려고 한다.

(https://github.com/aruymeek/python_basic/tree/master/modeltest)

 

1. 클래스 정의하기

먼저, 배우 정보 관리에 사용될 클래스를 생성하면, 아래처럼 만들어볼 수 있다.

class ActorModel:
    movie_key = ''
    name = ''
    age = 0

    def __init__(self, _key, _name, _age):
        self.movie_key = _key
        self.name = _name
        self.age = _age

    def ShowActorInfo(self):
        print('Movie Key: {0}, Name: {1}, Age: {2}'.format(self.movie_key, self.name, self.age))

    def Hello(self):
        print('안녕하세요. {0}입니다.'.format(self.name))

ActorModel 클래스를 통해 생성된 객체는 movie_key, name, age라는 클래스 속성을 갖는다. 배우가 출연한 영화의 고유 번호와, 배우 이름, 나이를 출력해주는 ShowActorInfo 메서드와, '안녕하세요 {배우이름}입니다.'를 출력하도록 하는 Hello 메서드도 포함되어 있다.

 

감독 정보를 다룰 DirectorModel 클래스도 비슷하게 생성했다.

class DirectorModel:
    movie_key = ''
    name = ''

    def __init__(self, _key, _name):
        self.movie_key = _key
        self.name = _name

    def ShowDirectorInfo(self):
        print('Movie Key: {0}, Name: {1}'.format(self.movie_key, self.name))

클래스 속성으로 movie_keyname을 갖고 있다. 배우 클래스와 마찬가지로 연출한 영화의 고유 번호와 감독 이름을 출력하는 ShowDirectorInfo 메서드가 포함되어 있다.

 

클래스 내에서 또 다른 클래스를 호출하여 사용할 수도 있는데, 배우/감독 클래스를 호출하여 영화 정보 클래스를 만들면 아래와 같다.

class MovieModel:
    movie_key = ''
    title = ''
    year = 2020
    nation = ''
 
    def __init__(self, _key, _title, _year, _nation):
        self.movie_key = _key
        self.title = _title
        self.year = _year
        self.nation = _nation
        self.actors = []
        self.directors = [] 

    def ShowMovieInfo(self):
        print('Movie Key: {0}, Title: {1}, Release: {2}, Nation: {3}'.format(self.movie_key, self.title, self.year, self.nation))
        print('등록된 배우 수: {0}'.format(len(self.actors)))
        print('등록된 감독 수: {0}'.format(len(self.directors)))    

    def AddActor(self, _name, _age):
        actor = ActorModel(self.movie_key, _name, _age)
        self.actors.append(actor)

    def AddDirector(self, _name):
        director = DirectorModel(self.movie_key, _name)
        self.directors.append(director)

MovieModel 클래스로 생성된 객체는 초기값으로 movie_key(영화 고유 번호), title(영화 제목), year(개봉년도), nation(제작 국가) 값을 갖는다. 생성자에 의해 actorsdirectors라는 빈 리스트를 갖게 되면서 같은 영화끼리 배우 목록과 감독 목록을 공유하게 된다. 만약, 이 두 가지가 클래스 속성이었다면 MovieModel 클래스로 생성되는 영화 정보는 모두 같은 배우, 같은 감독 정보를 갖게 되니 주의해야 한다.

 

ShowMovieInfo 메서드는 영화 고유 번호, 제목, 개봉년도, 국가 정보와 해당 영화에 등록된 배우의 수, 해당 영화에 등록된 감독의 수 등의 정보를 출력한다.

 

ActorModel 클래스를 호출하여 만든 메서드 AddActor는 배우의 이름과 나이를 입력받아 actor라는 객체를 생성한 후 actors 리스트에 정보를 추가하는 역할을 한다. 여기서 self.movie_keyMovieModel 클래스로 만든 객체의 movie_key를 그대로 사용하겠다는 것을 의미한다.

마찬가지로, DirectorModel 클래스를 호출하여 만든 메서드 AddDirector도 감독의 이름을 입력받아 director라는 객체를 생성한 후에 directors 리스트에 정보를 추가한다.

 

2. 클래스 관계 확인하기

지금까지 만든 클래스가 어떻게 동작하는지 확인해보자.

AboutTime = MovieModel('MOV001', '어바웃 타임', 2013, '영국')
print(type(AboutTime))

MovieModel class로 영화 고유번호는 'MOV001', 제목은 '어바웃 타임', 개봉년도는 2013, 제작국가는 '영국'인 AboutTime이라는 객체를 생성했다. 이 객체의 type을 출력해보면,

위와 같은 결과를 반환한다. MovieModel 클래스가 AboutTime의 type이 되는 것이다.

 

배우 정보는 어떻게 하면 될까?

Rachel = ActorModel('MOV001', '레이첼 맥아담스', 43)
Domhnall = ActorModel('MOV001', '도널 글리슨', 38)

ActorModel 클래스를 활용해 Rachel, Domhnall이라는 객체를 각각 생성했다. ActorModel 클래스에는 Hello라는 메서드가 있다. 각 객체에 Hello 메서드를 사용해 볼 수 있다.

Rachel.Hello()
Domhnall.Hello()

배우 이름이 잘 출력된 것을 확인할 수 있다.

 

생성된 RachelDomhnall 객체를 AboutTime의 배우 리스트에 추가해보자.

AboutTime.actors.append(Rachel)
AboutTime.actors.append(Domhnall)

# AboutTime.actors = [Rachel, Domhnall]

append()로 각각 넣어줘도 되고, 아래 주석처리 한 부분과 같이 AboutTime.actors에 리스트 형태로 할당해주어도 같은 결과이다.

 

다른 방법으로 '빌 나이' 배우의 정보를 추가해보자.

AboutTime.AddActor('빌 나이', 72)

사실, 배우 객체를 생성하고, 리스트에 추가하는 과정을 위와 같이 AddActor로 간단하게 처리할 수 있다. MovieModel로 만든 객체는 AddActor 메서드를 통해 ActorModel 클래스를 호출하여 사용할 수 있기 때문이다.

 

'리차드 커티스' 감독 정보도 아래처럼 AddDirector를 활용해 추가할 수 있다.

AboutTime.AddDirector('리차드 커티스')

# AboutTime.directors.append(DirectorModel('MOV001', '리차드 커티스'))

 

AboutTime 객체의 여러 속성값들을 출력해보자.

print(AboutTime.movie_key)     
print(AboutTime.title)         
print(AboutTime.year)          
print(AboutTime.nation)        
print(AboutTime.actors[0].name)
print(AboutTime.actors[1].name)

영화의 고유 번호와, 제목, 개봉년도, 국가, 첫번째 배우의 이름, 두번째 배우의 이름을 출력하는 코드이다. 결과값이 잘 출력된 것을 확인할 수 있다.

 

이것도 마찬가지로, 메서드로 간단하게 처리할 수 있다.

for actor in AboutTime.actors:
    actor.ShowActorInfo()

for director in AboutTime.directors:
    director.ShowDirectorInfo()

actorsdirectors가 갖고 있는 값은 각각 ActorModelDirectorModel 클래스로 생성된 객체이므로 ShowActorInfoShowDirectorInfo 메서드를 사용할 수 있다. actorsdirectorsMovieModel의 인스턴스이므로 Show~Info 메서드를 사용할 수 없다. 그래서 for문을 이용해 각 값에 대해 메서드를 사용할 수 있도록 했다.

 

3. 메인 과정

먼저, movies라는 리스트를 만들어 영화 정보를 추가할 수 있도록 한다.

movies = []

 

어바웃 타임(AboutTime), 기생충(Parasite), 어벤져스(Avengers4) 세 개의 영화를 추가해보았다.

# 첫번째 영화 추가
AboutTime = MovieModel('MOV001', '어바웃 타임', 2013, '영국')

AboutTime.AddActor('레이첼 맥아담스', 43)
AboutTime.AddActor('도널 글리슨', 38)

movies.append(AboutTime)

AboutTime.AddDirector('리차드 커티스')


# 두번째 영화 추가
Parasite = MovieModel('MOV002', '기생충', 2019, '한국')

Parasite.AddActor('최우식', 31)

movies.append(Parasite)

Parasite.AddDirector('봉준호')


# 세번째 영화 추가
Avengers4 = MovieModel('MOV003', '어벤져스: 엔드게임', 2019, '미국')

Avengers4.AddActor('로버트 다우니 주니어', 56)
Avengers4.AddActor('크리스 에반스', 40)
Avengers4.AddActor('크리스 헴스워스', 38)

Avengers4.AddDirector('앤소니 루소')
Avengers4.AddDirector('조 루소')

movies.append(Avengers4)

 

for문을 사용해서, 각 영화의 정보를 간단하게 출력해볼 수 있다.

그 전에, class 정보들을 출력할 때에 유의해야할 점이 있다.

print(movies)

movies 리스트에는 MovieModel 클래스로 만든 객체들이 값으로 들어가있다. 따라서, 그냥 print()를 하면 값을 바로 확인하기가 어렵다.

print(movies[0].title)

리스트 index로 특정 객체만 선택하여 클래스 속성을 이용할 때 온전한 값을 출력할 수 있다. 위의 결과로는 어바웃 타임이 정상적으로 출력된다.

 

이제, for문으로 movies 객체들의 정보를 출력한다.

for movie in movies:
    print('{0} | {1} | {2}'.format(movie.title, movie.nation, movie.year))

    for director in movie.directors:
        print('    - 감독: {0}'.format(director.name))

    for actor in movie.actors:
        print('    - 배우: {0}, {1}세'.format(actor.name, actor.age))

완성! 특이점은 어바웃 타임과 기생충은 배우 정보까지만 입력하고 movies에 추가한 후에 감독 정보를 추가하였는데도, 정보를 출력하니 모두 다 잘 나오고 있다.