추상클래스의 작동 방식

2024년 8월 28일 수요일

Today I Learned

날짜

2024년 8월 28일 수요일

내용

전환데이터의 종류

네이버 검색광고에도 전환 데이터에 대한 타입이 추가되었다. 제공되는 전환수와 값이 어떤 전환에 대한 데이터인지를 구분해서 준다. 회원가입, 장바구니 담기, 구매 완료, 등등 8가지 종류가 있다는데 정확히 무엇을 의미하는지는 나도 몰?루. 그냥 나눠서 제공해야하니 구현했다.

처음엔 일단 모든 데이터를 가져오되, 현재는 합쳐져 있는 데이터를 전환 종류에 따라 분류해서 들고있으려고 했다. 모두 들고 저장은 하되, 구글 스프레드시트에 넣을 때만 필요한 전환 종류의 데이터만 넣도록 만드는게 목표였다. 이유는

  1. 전환 종류를 바꾸더라도 삽입하는 데이터만 변경하면 되므로, 매 번 데이터를 불러오고 처리하는 작업이 필요하지 않다.
  2. 다른 플랫폼에선 전환 값이 훨씬 다양해지므로 1번의 장점이 더 극대화될 수 있다.

는 점이었다. 하지만 구현과정에서 어려움이 상당히 컸다.

네이버에서 데이터를 가져올 때 2~3가지의 보고서를 수백개 만들어서 가져온다. 다른 종류의 보고서에서 같은 기준을 나타내는 데이터를 “조인” 하는게 핵심 로직이다.

예를 들어

  1. 광고 성과 보고서

    날짜 캠페인 광고그룹 키워드 노출수 클릭수
    7월 19일 그룹 A 알파리뷰 12 8
    7월 19일 그룹 A 리뷰솔루션 75 25
    7월 19일 그룹 A 카페24리뷰 92 43
  2. 전환 보고서

    날짜 캠페인 광고그룹 키워드 전환종류 전환값
    7월 19일 그룹 A 알파리뷰 구매완료 4
    7월 19일 그룹 A 카페24리뷰 회원가입 11
    7월 19일 그룹 B studiomx 예약 14

각 날짜별로 두 가지 보고서가 위와 같이 생성된다. 이 둘을 캠페인, 광고그룹, 키워드 를 기준으로 하여 같은 것끼리 묶어준다. 그러면

날짜 캠페인 광고그룹 키워드 노출수 클릭수 전환값
7월 19일 그룹 A 알파리뷰 12 8 4
7월 19일 그룹 A 리뷰솔루션 75 25 0
7월 19일 그룹 A 카페24리뷰 0 0 11
7월 19일 그룹 B studiomx 0 0 14

이런 형태가 된다. 이걸 스프레드시트에 넣어주면된다. 근데 여기에 “전환 종류”가 추가되야 한다.. 그럼 광고 성과보고서 데이터 1행과 조인해야할 행이 전환보고서상에서 여러개가 된다는 의미다. 캠페인 가, 광고그룹 A, 키워드 알파리뷰 데이터는 광고 성과보고서에선 행 1개에 존재하지만 전환 보고서에선 전환 종류에 따라 최대 8개까지 존재할 수 있다. 그렇다고 1행에 존재하는 데이터에 미리 전환 종류별로 8개를 복제해놓으면 데이터 처리 시간은 8배가 되버릴 수 있으니 마냥 좋은 방법도 아니다.

알아보니 이 전환 종류는 사용자가 자주 바꾸지 않을 데이터라고 한다. 구매완료 데이터만 가져오던 사람이 내일은 위시리스트 추가 데이터를 가져올 경우는 상당히 드문 모양이다. 그렇다면 이 방식을 고수하고자 했던 근거가 미약해진다. 따라서 데이터 처리 시간이 길어지는 걸 감수할 이유가 전혀없다.

그래서 보고서에서 전환 종류에 맞는 데이터만 가져오도록 수정했다. 오히려 보고서에서 전환 종류에 맞는 데이터만 가져오니 데이터 처리 로직의 수행 시간은 감소했다!

생각보다 기깔난 추상클래스

각 로우데이터 별로 로직이 거진 비슷해서 관련 클래스를 추상클래스로 만들었다. 그러다 문득 추상 메서드의 작 방식에 대해 궁금해졌다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
from abc import ABC, abstractmethod

class calculator(ABC):
	def __init__(self, num_1, num_2):
		self.num_1 = num_1
		self.num_2 = num_2
		
	@abstractmethod
	def change_num_1(self):
		return self.num_1 * 2
		
	@abstractmethod
	def change_num_2(self):
		return self.num_2 * 2
		
	# 애만 추상메서드로 만들지 않음
	def add_secret_num(self):
		return 600
		
	def sum_numbers(self):
		res = self.change_num_1() + self.change_num_2() + self.add_secret_num()
		return res
	
	
class temu_calculator(calculator):
	def __init__(self, num1, num2):
		super().__init__(num1, num2)
		
	def change_num_1(self):
		return super().change_num_1()
		
	def change_num_2(self):
		return super().change_num_2()
		
	def sum_numbers(self):
		return super().sum_numbers()
		
exam = temu_calculator(5, 7).sum_numbers()

print(exam)

// 624

# 상속받은 클래스(temu_calculator)에 구현되지 않은 메서드라도 작동함
# (5*2) + (7*2) + 600

상속받은 클래스는 직접 구현하지 않은 메서드라도 부모가 구현했다면 사용할 수 있다. 그런데… 뭔가 내가 추상메서드에 대해 잘못쓰고있는 것 같다는 위화감을 느꼈다. 부모 클래스와 똑같이 행동하는 메서드 들을 굳이 상속할 필요가 있나? 그래서 테스트하나 더해봤다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from abc import ABC

# 추상메서드는 사용하지 않음
class calculator(ABC):
	def __init__(self, num_1, num_2):
		self.num_1 = num_1
		self.num_2 = num_2
		
	def change_num_1(self):
		return self.num_1 * 2
		
	def change_num_2(self):
		return self.num_2 * 2
		
	def add_secret_num(self):
		return 600
	
	def sum_numbers(self):
		res = self.change_num_1() + self.change_num_2() + self.add_secret_num()
		return res
	
# 기존과 달리 똑같이 작동하는 메서드들을 아에 정의하지 않음
class temu_calculator(calculator):
	def __init__(self, num1, num2):
		super().__init__(num1, num2)
		
exam = temu_calculator(5, 7).sum_numbers()

print(exam)

# 정의하지 않았어도 작동 잘함
// 624

똑같이 행동하는 메서드는 정의할 필요가 없는데… 바보짓하고 있었다.

회고

나는 데이터가 싫어요