Error instantiating python OO objects

Asked

Viewed 594 times

3

Guys, I will gather here in this message two questions of python OO. Anaconda use (python 3.6.1).

I’m trying to make a little project to study object orientation in python 3.6.1. Initially, the problem is when to pass the parameters to the constructor.

# coding: UTF-8
from automovel import Veiculo

class Veiculo(object):

    #como atribuo valores de instância para essas variáveis como no java, por exemplo?

    placa=None
    cor=None
    cidade=None

    #construtor

    def __init__(self, placa, cidade, cor):
        self.placa=placa
        self.cor=cor
        self.cidade=cidade

    # a linha abaixo não dá erro, mas não usa o construtor
    carro=Veiculo

    # a linha abaixo dá erro e nem usa o construtor
    carro2 = Veiculo("JFW3128", "Salvador", "preto")

The mistake:

Description Resource Path Location Type Unresolved import: Vehicle auto.py /automoveis line 7 Pydev Problem

Already without the import line, gives the error:

Description Resource Path Location Type Undefined variable: Vehicle car.py /cars line 13 Pydev Problem

Note, the file name is automovel.py. I use the eclipse IDE with pydev installed.

I know there are as many theories in the OO, as in the link:

Python assignment and OO

I prefer to stick to the concrete part.

On this link, it seems to me that python OO works smoothly (python v2):

Print a list of objects as string in Python

Already the same doubt to follow there was no return of user satisfaction:

Problem instantiating classes in Python 3

  • 1

    The file name is Veiculo, what matters the module Veiculo (himself) and defines a class Veiculo? That’s the mistake. What exactly is this import?

  • @Anderson Carlos Woss already tried with the different name for the file, but I didn’t notice much change. The Vehicle import is the class and, consequently, the file. I believe that even so should not give error because python does not take into account the file name. There are framework, for example, that have several classes in the same file.

  • The file name will be the module name, so it’s taken into account, yes. The question is, why are you importing the module into itself, since it itself defines the class? The name conflict is between the module name and the class name, it cannot be the same.

  • @Anderson Carlos Woss renewed the project, reviewed the errors and edited the question.

  • 2

    But are you still importing the module itself into itself? That doesn’t make sense. Why the import automovel within the archive itself automovel?

  • @Anderson Carlos Woss why the class import into the file itself is cited in the question, pointing to the second error shown.

  • you are embodying the same class within itself when you report that car 2 = Vehicle ? maybe the error is there, because you may end up generating an eternal loop, try to call out of that class

Show 2 more comments

2 answers

3

There are two problems there. Let’s go in parts, first remove this import line and remove indentation of the variable car and caro2:

class Veiculo(object):

    placa=None
    cor=None
    cidade=None

    #construtor

    def __init__(self, placa, cidade, cor):
        self.placa=placa
        self.cor=cor
        self.cidade=cidade

# Se as linhas abaixo estiverem indentadas como estavam inicialmente,
# ou seja, no mesmo nível de Veiculo,
# significa que as variáveis fazem parte da classe Veiculo, e você
# não vai conseguir declarar uma var Veiculo dentro dele mesmo

carro = Veiculo
carro2 = Veiculo("JFW3128", "Salvador", "preto")

Now you can crop variables car and carro2 and save the file only with the class Vehicle, and then yes import it into another file, and paste the car lines and carro2 into this new file

3


You are thinking very "javamente". This code there can be pythonizado.

In python, what defines the scope is indentation.

For example:

def function(a):
    if a is None:
        b = 100
        return b

    if a > 300:
        c = 90
        return a + c

    #erro, b e c não estão definidas nesse escopo.
    # b só pode ser referenciada dentro do primeiro if.
    # c só pode ser referenciada dentro do segundo if.
    return c*b*90

In your case, your class Veiculo has within its scope everything that is indented with four spaces or a tab, which are:

  • The variables you defined: placa, cor and cidade.
  • The builder: def __init__(self, placa, cidade, cor).
  • And the calls: carro=Veiculo and carro2 = Veiculo("JFW3128", "Salvador", "preto")

First point, you do not need to declare variables before assigning some value to them. That is, it is useless to do this:

placa=None
cor=None
cidade=None

You don’t need to extend Veiculo à Object. It’s the same thing as doing: class Veiculo:

Whenever you give one self.attr you will be creating a class attribute if it does not exist yet. According to PEP8, all attributes of the class must be created in the constructor. That is, their first declaration must be in the __init__. At this point, your code is right.

You do not need to import a module if you already have access to it. So, it is also useless to do the import you did.

Pythonized code:

class Veiculo:

    def __init__(self, placa, cidade, cor):
        self.placa = placa
        self.cor = cor
        self.cidade = cidade

    def __str__(self) -> str:
        return "({0};{1};{2})".format(self.placa, self.cor, self.cidade)


if __name__ == "__main__":
    carro = Veiculo
    carro2 = Veiculo("JFW3128", "Salvador", "preto")
    print(carro)
    print(carro2)

Because if __name__ == "__main__":?

The python interpreter executes all the code as it reads it. If, for some reason, in another file you give a from automovel import Veiculo and has no such variable check __name__ it will run that part of the code without you having called python automovel.py. That is, it will only execute that part of the code if the execution of the script is done by python automovel.py.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.