Тип списка не может быть вызван

#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 Я обновил свой ответ, чтобы объяснить.