학습 목표
- 캡슐화 이해하기
- IsConnect 함수 캡슐화하기
캡슐화라는 것은 특정 함수를 어디서 호출하든지 간에 동일한 논리 구조에 따라 동작하는 함수를 생성하는 것이라 생각하면 된다. 이번 게시글에서는 `IsConnect()` 함수를 하나의 캡슐화를 통해 프로그램 실행과 동시에 연결 성공 여부를 판단하도록 하는 함수를 제작할 예정이다.
(1) 캡슐화란
기본적으로 A라는 값을 전달했을 때 A라는 숫자에 10을 더한 숫자를 반환해주는 기능을 구현하고 싶다고 가정해보자. 그렇다면 캡슐화라는 이름을 가진 함수(`capsulation()`)는 A와 같이 특정 값을 전달받아야 하는데, 이를 함수의 인자(parameter)라고 한다. 함수는 얼마든지 많은 인자를 전달받을 수 있고 인자를 전달받지 않고도 얼마든지 구현할 수 있다. 일단 캡슐화를 이해하기 위해 A라는 하나의 인자를 전달받으면 그 인자에 10을 더한 값을 반환해주는 함수를 구현해보도록 하자.
def capsulation(value):
print(value+10)
이제 이 함수에 5라는 숫자를 전달하면 5에 10을 더한 15을 출력할 것이고, 100을 전달하면 100에 10을 더한 110을 출력할 것이다. 이 때 이 함수에 인자를 전달하는 방법은 `capsulation(5)` 또는 `capsulation(100)`과 같은 형태를 갖는다.
capsulation(5)
15
capsulation(100)
110
위와 같이 하나의 인자를 전달받는 함수도 있겠지만, 두 개 이상의 인자를 전달받는 함수도 있다. 위의 예제보다 조금 더 복잡한 사례를 살펴보도록 하자. 예를 들어 A와 B, C라는 세 개의 인자를 요구하는 동시에 A와 B, C 모두를 곱한 값에 10을 더한 값을 출력하는 함수를 구현해보자.
def capsulation(a, b, c):
print(a * b * c + 10)
이러한 구조의 함수 역시 사용 방법은 위와 동일하게, `capsulation(1, 1, 1)` 또는 `capsulation(2, 2, 2)` 등과 같이 사용할 수 있다.
capsulation(1, 1, 1)
11
capsulation(2, 2, 2)
18
(2) IsConnect 함수 캡슐화
위에서 살펴본 내용과 같이 함수는 여러 개의 인자를 받을 수도 있겠지만, 단 하나의 인자도 필요로 하지 않을 수도 있다. 위의 예제에서 캡슐화된 함수의 사용 방법을 익혔으니 여기서부터는 대신증권에서 제공하는 `IsConnect()` 함수를 하나의 캡슐로 만들고 그 캡슐을 호출하는 방법에 대해 알아보도록 하자. 의외로 직접 만들어보면, 별 게 아니라는 생각이 들 것이다.
import win32com.client
class cybos:
def __init__(self):
self.cybos = win32com.client.Dispatch("CpUtil.CpCybos") ## COM 연결
def _IsConnect(self):
value = self.cybos.IsConnect
print(value)
if __name__ == "__main__":
cybos()
이제 이 캡슐화된 함수를 사용하는 방법은 두 가지가 있다. 먼저 첫 번째 방법은 맨 아래 줄에 있는 `cybos()` 뒤에 함수를 직접 기재해서 그 함수를 지정하여 실행하는 방법이고, 두 번째 방법은 `def __init__(self)` 함수 내에 함수를 기재해서 우리가 제작하고 있는 `cybos()` 클래스가 실행되면 자동으로 실행되도록 하는 방법이다. 먼저 첫 번째 방법부터 시도해보자.
import win32com.client
class cybos:
def __init__(self):
self.cybos = win32com.client.Dispatch("CpUtil.CpCybos") ## COM 연결
def _IsConnect(self):
value = self.cybos.IsConnect
print(value)
if __name__ == "__main__":
cybos()._IsConnect()
▶ 실행 결과 확인하기
이제 두 번째 방법인데, 이 방법은 이전에 사용해왔던 방법과 동일하게 `cybos()`만 호출하면 자동으로 서버와의 연결 여부를 확인해주는 방식이다. 이 코드를 제작하기 전에 앞서, 우리는 `self`란 어떤 역할로 사용되는지에 대해 이해할 필요가 있다. 앞서 제작한 첫 번째 방법의 경우에는 `cybos()._IsConnect()`와 같이 사용하여 해당 함수를 호출했었는데, 아래의 두 번째 방법의 경우에는 `cybos()`만을 실행하되 `def __init__(self)` 함수 내에서 `self._IsConnect()`와 같이 사용하여 해당 함수를 호출하고 있다.
여기서 `cybos()._IsConnect()`와 `self._IsConnect()`의 차이라 함은 첫 번째 방법에서는 `cybos()`를 사용했던 자리에 두 번째 방법에서는 `self`가 들어간다는 것이다. 즉, `cybos()`라는 클래스 내에서는 `cybos()._IsConnect()`가 아니라, `cybos()`를 대체하는 `self`를 사용하여 함수를 실행할 수 있다.
import win32com.client
class cybos:
def __init__(self):
self.cybos = win32com.client.Dispatch("CpUtil.CpCybos") ## COM 연결
self._IsConnect()
def _IsConnect(self):
value = self.cybos.IsConnect
print(value)
if __name__ == "__main__":
cybos()
▶ 실행 결과 확인하기
결국에는 호출하는 방식에만 차이가 있을 뿐 실질적인 실행 결과는 동일하다. 그럼에도 두 번째 방식을 사용해야만 하는 이유가 있다면 첫 번째 방법의 경우에는 하나의 함수를 호출한 후에 그 함수의 실행이 종료된다면 다른 함수를 또 다시 제작해주어야 하지만, 두 번째 방법의 경우에는 하나의 함수를 호출하고도 해당 클래스를 종료시키지 않을 수 있기 때문이다. 어찌됐든 프로그램은 계속 돌아가야 하는데, 정작 서버와 연결되어 있는지만 확인하고 해당 클래스를 종료시켜버리면 우리가 제작하는 자동 매매 프로그램의 필요성이 없기 때문이다.
(3) IsConnect 함수 내부에서 연결 성공 여부 판단하기
이전 게시글에서 살펴봤듯이, `IsConnect()` 함수는 서버와의 연결이 성공했는지 실패했는지에 대해 각각 1과 0이라는 결과값을 전달한다. 그렇다면 우리는 `def _IsConnect()` 함수 내부에서 단순하게 그 결과값을 저장한 변수인 `value`를 `print()`문을 사용하여 출력만 하고 끝낼 것이 아니라, 조건문을 사용하여 서버와의 연결 여부를 판단해주어야 한다. 왜냐하면 서버와 연결이 되지 않았다면 프로그램을 다시 실행하던지 해야하기 때문이다.
import win32com.client
class cybos:
def __init__(self):
self.cybos = win32com.client.Dispatch("CpUtil.CpCybos") ## COM 연결
self._IsConnect()
def _IsConnect(self):
value = self.cybos.IsConnect
if value == 1:
print("서버와의 연결에 성공했습니다.")
elif value == 0:
print("서버와의 연결에 실패했습니다.")
if __name__ == "__main__":
cybos()
▶ 실행 결과 확인하기
더보기
더보기
더보기
서버와의 연결에 성공했습니다.
종료 코드 0(으)로 완료된 프로세스
더 나아가, (물론 추후에는 로그 데이터를 살펴볼 예정이지만 `print()`문이든 `logging()`문이든 간에 공통적으로 적용되는 내용이다.) `print()` 문에서 단순하게 "서버와의 연결에 성공했습니다."라는 문구만 출력하도록 하고 있으나 사람에 따라서는 `value` 값과 상태메시지를 함께 확인하고 싶을 수도 있다. 이런 경우에는 `f"{ }"`와 같은 형태를 사용하여 중괄호 안에 변수명을 입력하고 그 외의 구간에는 단순한 문자를 입력하여 함께 확인할 수 있다. 아래의 예제를 살펴보자.
import win32com.client
class cybos:
def __init__(self):
self.cybos = win32com.client.Dispatch("CpUtil.CpCybos") ## COM 연결
self._IsConnect()
def _IsConnect(self):
value = self.cybos.IsConnect
if value == 1:
print(f"서버와의 연결에 성공했습니다.(value:{value})")
elif value == 0:
print(f"서버와의 연결에 실패했습니다.(value:{value})")
if __name__ == "__main__":
cybos()
▶ 실행 결과 확인하기
더보기
더보기
더보기
서버와의 연결에 성공했습니다.(value:1)
종료 코드 0(으)로 완료된 프로세스
value의 위치를 조금 더 수정해서 더 깔끔하고 직관적이게 표기할 수도 있다.
import win32com.client
class cybos:
def __init__(self):
self.cybos = win32com.client.Dispatch("CpUtil.CpCybos") ## COM 연결
self._IsConnect()
def _IsConnect(self):
value = self.cybos.IsConnect
if value == 1:
print(f"[통신결과:{value}] 서버와의 연결에 성공했습니다.")
elif value == 0:
print(f"[통신결과:{value}] 서버와의 연결에 실패했습니다.")
if __name__ == "__main__":
cybos()
▶ 실행 결과 확인하기
더보기
더보기
더보기
[통신결과:1] 서버와의 연결에 성공했습니다.
종료 코드 0(으)로 완료된 프로세스