我正在做 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(" !@#$%^&*()-_+={}[]|\:;'<>?,./\"")
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
'''
word_list = 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())
我已经查找了所有在代码中使用“list”作为变量的情况,但我没有这样做。我查了过去的答案,所有人都说当列表被用作我没有做过的变量时,列表类型不可调用。我已经处理了几个小时,但无法解决它。我突出显示了控制台出错的那一行。出了什么问题?我还必须在子类 CipherText 中定义 self.valid_words,因为代码不是从父类 Message 继承的。这是为什么?
答案 0 :(得分:1)
class Message(object):
def __init__(self, text):
self.message_text = text
self.valid_words = ['apple','banana','orange']
message1 = Message("hello")
以下会产生错误,因为 valid_words
是类 Message 的一个属性,并且通过添加括号,您试图像调用函数一样调用列表。正如您所提到的,这会产生以下错误:
words = message1.valid_words()
print(words)
output: TypeError: 'list' object is not callable
要解决这个问题,只需像这样删除括号:
words = message1.valid_words
print(words)
output: ['apple','banana','orange']
您可以阅读有关 Python here 中的对象的更多信息。
编辑:对继承问题的回应
在您的 CiphertextMessage 类中,您正在从 message 重写构造函数。如果它们完全相同,则不必这样做。相反,只需使用 super()
函数从父类访问构造函数。像这样,
class CiphertextMessage(Message):
def __init__(self, text):
super().__init__(text)
或者,您可以像这样显式地使用 Message 构造函数:
class CiphertextMessage(Message):
def __init__(self, text):
Message.__init__(self, text)
您可以阅读 Python 继承 here。