#python #oop #inheritance
Вопрос:
Я выполняю набор задач MIT OCW 6.0001 4. Это говорит мне, что тип списка не может быть вызван. Но я не присваивал термин «список» какому-либо объекту. Вот мой код:
import string
def load_words(file_name):
print("Loading word list from file...")
inFile = open(file_name, 'r')
wordlist = []
for line in inFile:
wordlist.extend([word.lower() for word in line.split(' ')])
print(" ", len(wordlist), "words loaded.")
return wordlist
def is_word(word_list, word):
word = word.lower()
word = word.strip(" !@#$%^amp;*()-_ ={}[]|:;'<>?,./"")
return word in word_list
def get_story_string():
"""
Returns: a story in encrypted text.
"""
f = open("story.txt", "r")
story = str(f.read())
f.close()
return story
### END HELPER CODE ###
WORDLIST_FILENAME = 'words.txt'
class Message(object):
def __init__(self, text):
self.message_text = text
self.valid_words = load_words(WORDLIST_FILENAME)
def get_message_text(self):
return self.message_text
def get_valid_words(self):
word_copy = self.valid_words[:]
return word_copy
def build_shift_dict(self, bshift):
alphabet_lower = string.ascii_lowercase
alphabet_upper = string.ascii_uppercase
alphabet_dict={}
n=0
for i in range(26):
if i bshift <= 25:
alphabet_dict[alphabet_lower[i]] = alphabet_lower[i bshift]
alphabet_dict[alphabet_upper[i]] = alphabet_upper[i bshift]
else:
alphabet_dict[alphabet_lower[i]]=alphabet_lower[n]
alphabet_dict[alphabet_upper[i]]=alphabet_upper[n]
n =1
return alphabet_dict
def apply_shift(self, shift):
alphabet_dictio = self.build_shift_dict(self.get_shift())
alphabet_keys= alphabet_dictio.keys()
enc_msg_list = []
for char in self.message_text:
if char in alphabet_keys:
beta = alphabet_dictio[char]
enc_msg_list.append(beta)
else:
enc_msg_list.append(char)
enc_message_string =""
for t in enc_msg_list:
enc_message_string =t
return enc_message_string
class CiphertextMessage(Message):
def __init__(self, text):
'''
Initializes a CiphertextMessage object
text (string): the message's text
a CiphertextMessage object has two attributes:
self.message_text (string, determined by input text)
self.valid_words (list, determined using helper function load_words)
'''
self.message_text = text
self.valid_words = load_words(WORDLIST_FILENAME)
def decrypt_message(self):
'''
Decrypt self.message_text by trying every possible shift value
and find the "best" one. We will define "best" as the shift that
creates the maximum number of real words when we use apply_shift(shift)
on the message text.
Note: if multiple shifts are equally good such that they all create
the maximum number of valid words, you may choose any of those shifts
(and their corresponding decrypted messages) to return
Returns: a tuple of the best shift value used to decrypt the message
and the decrypted message text using that shift value
'''
список слов = self.valid_words()
ЭТО СТРОКА С ОШИБКОЙ
encr_msg_list = self.message_text.split()
c=0
pala =""
for dec_key in range(26):
attempt_dict = self.build_shift_dict(dec_key)
givenlist1 = attempt_dict.values()
givenlist=[]
for owmwo in givenlist1:
givenlist.append(owmwo)
correctlist1 = attempt_dict.keys()
correctlist =[]
for wop in correctlist1:
correctlist.append(wop)
oompa =[]
n=0
for elem1 in encr_msg_list:
word = ""
for char in elem1:
if char in string.ascii_letters:
poop = givenlist.index(char)
poop1 = correctlist[poop]
word = poop1
else:
word = char
oompa.append(word)
if word in is_word(word_list, word):
n =1
if n > c:
c = dec_key
for words1 in oompa:
pala = word " "
return (dec_key, pala)
class PlaintextMessage(Message):
def __init__(self, text, shift):
'''
Initializes a PlaintextMessage object
text (string): the message's text
shift (integer): the shift associated with this message
A PlaintextMessage object inherits from Message and has five attributes:
self.message_text (string, determined by input text)
self.valid_words (list, determined using helper function load_words)
self.shift (integer, determined by input shift)
self.encryption_dict (dictionary, built using shift)
self.message_text_encrypted (string, created using shift)
'''
self.message_text = text
self.shift = int(shift)
self.encryption_dict = self.build_shift_dict(self.get_shift())
self.message_text_encrypted = self.apply_shift(self.get_shift())
def get_shift(self):
'''
Used to safely access self.shift outside of the class
Returns: self.shift
'''
return int(self.shift)
def get_encryption_dict(self):
'''
Used to safely access a copy self.encryption_dict outside of the class
Returns: a COPY of self.encryption_dict
'''
# boom = self.get_shift()
shifted_dict = self.build_shift_dict(self.get_shift())
shifted_dict1 = shifted_dict.copy()
return shifted_dict1
def get_message_text_encrypted(self):
return self.message_text_encrypted
def change_shift(self, shift):
self.shift = shift
self.message_text_encrypted = self.apply_shift(self.get_shift())
Я искал все случаи использования «списка» в качестве переменной в коде, но я этого не сделал. Я просмотрел прошлые ответы, и все сказали, что тип списка не вызывается, когда список использовался в качестве переменной, чего я не делал. Я занимаюсь этим уже несколько часов и так и не смог решить эту проблему. Я выделил строку, в которой консоль выдает ошибку. Что происходит не так ? Мне также пришлось определить self.valid_words в зашифрованном тексте подкласса, поскольку код не наследует его от сообщения родительского класса. Это почему?
Ответ №1:
class Message(object):
def __init__(self, text):
self.message_text = text
self.valid_words = ['apple','banana','orange']
message1 = Message("hello")
Это следующее создает ошибку, потому valid_words
что является атрибутом сообщения класса, и, добавляя круглые скобки, вы пытаетесь вызвать список как функцию. Это приводит к следующей ошибке, как вы упомянули:
words = message1.valid_words()
print(words)
output: TypeError: 'list' object is not callable
Чтобы исправить это, просто удалите скобки, как это:
words = message1.valid_words
print(words)
output: ['apple','banana','orange']
Вы можете прочитать больше об объектах в Python здесь.
Изменить: Ответ на вопрос о наследовании
В своем классе CiphertextMessage вы переписываете конструктор из сообщения. Вам не нужно этого делать, если они точно такие же. Вместо этого просто используйте super()
функцию для доступа к конструктору из родительского класса. Подобный этому,
class CiphertextMessage(Message):
def __init__(self, text):
super().__init__(text)
В качестве альтернативы вы можете явно использовать конструктор сообщений следующим образом:
class CiphertextMessage(Message):
def __init__(self, text):
Message.__init__(self, text)
Вы можете прочитать о наследовании Python здесь.
Комментарии:
1. @fr4nco Большое вам за это спасибо. Я использовал материал в консоли, и там нужны были кронштейны. Не могли бы вы также, пожалуйста, сказать мне, почему подклассы не наследуют методы инициализации def от родительского класса ? Когда я попытался сделать Cipertext.valid_word, это говорит мне, что допустимое слово не является атрибутом подкласса cipertext
2. @ShauryaGoyal Я обновил свой ответ, чтобы объяснить.