Python
OOP - 상속,변수, 초기화- Crawling/Custom Exceptions
foxlee
2022. 1. 13. 18:04
- 클래스 변수 - 모든 인스턴스가 변경, 모든 클래스에서 공유
- 인스턴스 변수 - 인스턴스 마다 사용, 해당 인스턴스만 사용, 클래스 객체에서 접근 불가능
- 클래스 변수에 접근할 때는 특별히 이유가 없다면
- '인스턴스.클래스변수' 나 'self.클래스변수'와 같이 접근하는 것을 피해야함
- 방법
- cls.변수(클래스메소드 안에서),
- Class.변수(클래스 외부에서)
- type(self).변수(메소드내)
- 인스턴스 변수를 인스턴스 객체로부터 생성하는 것이 가능하므로 의도치 않게 클래스 변수를 인스턴스 변수로 은폐해버릴 수 있음 -> 인스턴스 변수와 클래스 변수 혼용하지 말것
class Crawler:
# 크롤링을 하며 인스턴스마다 다른/저장하는 데이터들은 인스턴스 변수에 저장
def __init__(self, logging):
self._logging = logging
self._parse_url = ""
self._doc = None
self._definitions = []
self._examples = []
# Class variable 접근 시 type(self).variable 로 접근
def parse(self):
dictionary_cards = self.find_elements(type(self)._dictionary_cards)
for dict_card in dictionary_cards:
self._examples.extend(
self.find_text_contents(dict_card, type(self)._example_element)
)
self._definitions.extend(
self.find_text_contents(dict_card, type(self)._definition_element)
)
self._logging.info(
f"parsed from {type(self)._site}, count : definition {len(self._definitions)}, example {len(self._examples)}"
)
def print_data(self):
print(f"""
url: {self._parse_url}
keyword: {self._keyword}
definitions: {len(self._definitions)}
examples: {len(self._examples)}
""")
class CrawlerCambridge(Crawler):
# 사이트별로 정해진 변수값들은 클래스 변수에 저장
_site = "Cambridge"
_url = "https://dictionary.cambridge.org/dictionary/english/"
_dictionary_cards = [["div", "dictionary"]]
_definition_element = ["div", ["def", "ddef_d", "db"]]
_example_element = ["span", "eg"]
def __init__(self, logging):
self._logging = logging # 지금 코드에서는 없어도 가능. _logging을 이 클래스에서 정의한 메서드에서 실행(접근)한다면 필요
Crawler.__init__(self, logging) # 부모 클래스를 초기화 해줌으로써 위에 _parse_url, _doc, 등의 변수를 인스턴스 생성시 같이 만들어짐
# 오버라이드 - 부모 함수 호출하여 반복 하지 않고 로직 추가 가능
def print_data(self):
print(f"site: {type(self)._site}")
super().print_data()
class FileError(Exception):
def __init__(self, filename="", message="File related error occurred"):
self.filename = filename
self.message = message
super().__init__(self.message)
def __str__(self):
if self.filename:
return f"{self.message}, file name : {self.filename}"
return f"{self.message}"
class FileSaveError(FileError):
def __init__(self, filename="", message="Fail to save the file"):
super().__init__(filename, message)
class FileRemoveError(FileError):
def __init__(self, filename="", message="Fail to remove the file"):
super().__init__(filename, message)
class FileExtractExtentionError(FileError):
def __init__(self, filename="", message="Fail to extract file extention"):
super().__init__(filename, message)
try:
raise FileError()
raise FileSaveError(filename="test.txt")
raise FileRemoveError()
raise FileError(filename="test.txt")
except Exception as e:
print(e.__str__())