列表类型不可调用

时间:2021-04-11 19:07:56

标签: 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(" !@#$%^&*()-_+={}[]|\:;'<>?,./\"")
        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 继承的。这是为什么?

1 个答案:

答案 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