#python #abstract-class #abstract
#python #абстрактный класс #аннотация
Вопрос:
Я пытаюсь реализовать код, который исправляет незначительные опечатки в данном слове. Эти слова являются именами собственными, которые либо из списка городов, либо из штатов. Учитывая, что мы знаем, является ли опечатка из города или штата. Я пытаюсь реализовать два класса StateTypo
, CityTypo
которые являются подклассами базового класса, BaseTypo
.
Вот код для BaseTypo
и StateTypo
:
from collections import Counter
from abc import ABC, abstractmethod
class BaseTypo(ABC):
def __init__(self):
self.WORDS = self.dictionary()
self.N = sum(self.WORDS.values())
@abstractmethod
def dictionary(self):
return dict()
def known(self, words):
""""""
return set(w for w in words if w in self.WORDS)
def P(self, word):
"""Calculate probability of the given word"""
return self.WORDS[word] / self.N
def correction(self, word):
"""Most probable word"""
return max(self.candidates(word), key=self.P)
def candidates(self, word):
""" Generate possible correct words"""
return self.known([word]) or self.known(self.edits1(word)) or self.known(self.edits2(word)) or [word]
def edits1(self, word):
letters = 'abcdefghijklmnopqrstuvwxyz'
splits = [(word[:i], word[i:]) for i in range(len(word) 1)]
deletes = [L R[1:] for L, R in splits if R]
transposes = [L R[1] R[0] R[2:] for L, R in splits if len(R) > 1]
replaces = [L c R[1:] for L, R in splits if R for c in letters]
inserts = [L c R for L, R in splits for c in letters]
return set(deletes transposes replaces inserts)
def edits2(self, word):
return (e2 for e1 in self.edits1(word) for e2 in self.edits1(e1))
class StateTypo(BaseTypo):
def __init__(self):
super(BaseTypo, self).__init__()
self.address = 'states.txt'
def dictionary(self):
print(self.address)
with open(self.address, 'r') as file:
lines = file.readlines()
lines = [line.strip() for line in lines]
return Counter(lines)
if __name__ == '__main__':
a = StateTypo()
corrected = a.correction('himachal prfadesh')
print(corrected) # should ideally print himachal pradesh
Однако приведенный выше код приводит к следующей ошибке:
Traceback (most recent call last):
File "correctTypo.py", line 59, in <module>
corrected = a.correction('himachal prfadesh')
File "correctTypo.py", line 25, in correction
return max(self.candidates(word), key=self.P)
File "correctTypo.py", line 29, in candidates
return self.known([word]) or self.known(self.edits1(word)) or self.known(self.edits2(w
ord)) or [word]
File "correctTypo.py", line 17, in known
return set(w for w in words if w in self.WORDS)
File "correctTypo.py", line 17, in <genexpr>
return set(w for w in words if w in self.WORDS)
AttributeError: 'StateTypo' object has no attribute 'WORDS'
Теперь я знаю, что нам действительно не нужен абстрактный класс для реализации этого, но как я могу решить эту проблему, учитывая, что моя первоначальная идея о наличии абстрактного метода в базовом классе сохраняется?
Ответ №1:
super
означает супер, он дает вам супер объект.
Вы можете инициализировать базовый класс с помощью super(StateTypo, self).__init__()
или BaseTypo.__init__(self)
, но не super(BaseTypo, self).__init__()
.
И address
используется во время инициализации, поэтому он должен быть
class StateTypo(BaseTypo):
def __init__(self):
self.address = 'states.txt'
super(StateTypo, self).__init__()
Или вы можете изменить другой код, чтобы сохранить __init__
базовый класс в первой строке.