Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

name 'Serie' is not defined

Olá,

No curso, o professor executa alguns comandos direto no código para criar os objetos e printar as informações. Como por exemplo:

vingadores = Filme('vingadores - guerra infinita', 2018, 160)
atlanta = Serie('atlanta', 2018, 2)
vingadores.dar_likes()
atlanta.dar_likes()
print(f'Nome: {vingadores.nome} - Likes: {vingadores.likes}')
print(f'Nome: {atlanta.nome} - Likes: {atlanta.likes}')

Porém, também estou executando os mesmos comando pelo prompt do Visual Studio 2019, para dar mais likes ou alterar o nome do filme. Mas por algum motivo está dando um erro quando eu tento executar pelo prompt e eu já verifiquei todo o código, até com o código do professor da o mesmo problema.

>>> from modelo import Filme
Nome: Vingadores - Guerra Infinita - Likes: 3
Nome: Atlanta - Likes: 2
>>> atlanta = Serie('atlanta', 2018, 2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'Serie' is not defined

Ou seja, executando a linha de comando direto no código eu consigo criar um objeto atlanta, mas se eu fizer o mesmo comando no prompt, não vai.

Vou deixar meu código aqui pra ver se tem algum erro.

class Programa:
    def __init__(self, nome, ano):
        self._nome = nome.title()
        self.ano = ano
        self._likes = 0

    @property
    def likes (self):
        return self._likes

    def dar_likes(self):
        self._likes += 1

    @property
    def nome (self):
        return self._nome

    @nome.setter
    def nome (self, novo_nome):
        self._nome = novo_nome.title()

class Serie(Programa):

    def __init__(self, nome, ano, temporada):
        super().__init__(nome, ano)
        self.temporada = temporada

class Filme(Programa):

    def __init__(self, nome, ano, duracao):
        super().__init__(nome, ano)
        self.duracao = duracao

vingadores = Filme('vingadores - guerra infinita', 2018, 160)
atlanta = Serie('atlanta', 2018, 2)
vingadores.dar_likes()
vingadores.dar_likes()
vingadores.dar_likes()

atlanta.dar_likes()
atlanta.dar_likes()

print(f'Nome: {vingadores.nome} - Likes: {vingadores.likes}')
print(f'Nome: {atlanta.nome} - Likes: {atlanta.likes}')

filmes_e_series = [vingadores, atlanta]
2 respostas

Descobri o problema!

O prompt não conseguia encontrar a classe Serie quando eu executava diretamente por ele, porque eu tinha que ter importar todas as classes, no caso Filme e Serie.

>>> from modelo import Filme
>>> from modelo import Serie
>>> vingadores = Filme('vingadores - guerra infinita', 2018, 160)
>>> demolidor = Serie('Demolidor', 2016, 2)

Mas eu ainda não entendi como ele conseguia executar os comandos que estavam dentro do código e criar o objeto Atlanta, mesmo eu só importando a classe Filme, como demonstra abaixo.

>>> from modelo import Filmes
Vingadores - Guerra Infinita \ 2018 \ 160 minutos : 1 Likes
Atlanta \ 2018 \ 2 temporadas : 3 Likes
Demolidor \ 2016 \ 2 temporadas : 2 Likes
Todo Mundo Em Pânico \ 1999 \ 100 minutos : 4 Likes
solução!

Oii Bruno, como você está? Espero que esteja tudo bem por aí ^-^

Isso ocorre porque além de importar a classe pedida, o python leu todo o seu arquivo e observe que o código para a manipulação dos objetos não está dentro de uma função ou então, separado no bloco main (if __name__ == '__main__'), por isso ele apresentou o resultado do objeto Serie, pois o código para manipulação dos objetos estava no "código corrido", sem estar separado por uma função ou bloco main.

Imagine que cada classe seria uma caixinha, já a manipulação dos objetos está sem caixa alguma, então quando você realiza a importação, o que está dentro da caixa permanece na caixa, mas o que está fora, sem caixa alguma, é executado:

Modularização dos blocos de código, onde cada classe é um bloco de código, mas a manipulação dos objetos não tem um bloco de código

Se estivéssemos utilizando o trecho if __name__ == '__main__' para a manipulação dos objetos, colocando-o em uma "caixa", as mensagens que você visualizou ao importar a classe desapareceriam. E isso porque com esse trecho, dizemos ao python que o código dentro desse bloco só será executado se executarmos o programa principal, mas quando fizermos algum tipo de importação, esse trecho não será executado. Veja:

if __name__ == '__main__':
    vingadores = Filme('vingadores - guerra infinita', 2018, 160)
    atlanta = Serie('atlanta', 2018, 2)
    vingadores.dar_likes()
    vingadores.dar_likes()
    vingadores.dar_likes()

    atlanta.dar_likes()
    atlanta.dar_likes()

    print(f'Nome: {vingadores.nome} - Likes: {vingadores.likes}')
    print(f'Nome: {atlanta.nome} - Likes: {atlanta.likes}')

    filmes_e_series = [vingadores, atlanta]
>>> from modelo import Filme

Após essa alteração, observe que nada nos é apresentado, pois, através do if __name__ == '__main__' definimos uma "caixinha" para nosso código de manipulação dos objetos.

Vale ressaltar que é obrigatório quando estivermos executando o código pelo terminal ou em outro arquivo, importarmos explicitamente todas as funções e/ou classes que queremos utilizar.

Deixo como leitura complementar um artigo aqui da Alura que trata sobre a importância de modularizar o código:

Qualquer dúvida estou por aqui, tá bom?

Grande abraço!