Chris
Chris

Reputation: 9

Why do I get an Import Error( cannot import name) when trying to import the base class in the inherited class?

Hi I am writing a Bowling game with four classes; each in their own file but all in the same Directory/Folder; Game(uses all the other classes),Frame(are the turns, uses Roll),tenth_Frame(inherits from Frame), Roll (returns number of Pins). I get the Import Error cannot Import Name Frame in my tenth_Frame class. Also this is my first question here and I hope I included everything needed : )

I tried to figure it out, read multiple sites/QnA but couldnt find a solution. I tried to Change the Import but all I manage to get are different error Messages (Frame is not defined)

Game.py

from Module_Frame import*
from Roll import*
from tenth_Frame import*
class Game:....

Module_Frame.py

from Game import*
from Roll import*

class Frame():
    def __init__(self,game):
        self._score=0
        self._moves=Roll()
        self.game=game
        self.make_move()

Roll.py

import random 
from Module_Frame import*
from Game import *
#from tenth_Frame import*

class Roll:...

tenth_Frame.py

from Module_Frame import Frame

class tenth_Frame(Module_Frame.Frame):
    def __init__(self,game):

        Frame.__init__(self,game)
        self.__sum=0
        ...

I get the following result: ImportError: cannot Import Name Frame

File "j:\Programme\Marius Programmierphase.22.07.19\bowling\Game.py", line 2, in <module>
  from Module_Frame import*
File "j:\Programme\Marius Programmierphase.22.07.19\bowling\Module_Frame.py", line 2, in <module>
  from Game import*
File "j:\Programme\Marius Programmierphase.22.07.19\bowling\Game.py", line 3, in <module>
  from Roll import*
File "j:\Programme\Marius Programmierphase.22.07.19\bowling\Roll.py", line 5, in <module>
  from tenth_Frame import*
File "j:\Programme\Marius Programmierphase.22.07.19\bowling\tenth_Frame.py", line 5, in <module>
  class tenth_Frame(Module_Frame.Frame):

NameError: name 'Module_Frame' is not defined

So I also tried in tenth_Frame to Change the Import command to:

1.)

from Module_Frame import Frame

class tenth_Frame(Frame):

ImportError: cannot import name Frame

2.)

import Module_Frame

class tenth_Frame(Frame):

NameError: name 'Frame' is not defined

3.)

import Module_Frame

class tenth_Frame(Module_Frame.Frame):
AttributeError: 'module' object has no attribute 'Frame'

4.)

from Module_Frame import *

class tenth_Frame(Module_Frame.Frame):

NameError: name 'Module_Frame' is not defined

I read about dependencies and many other Errors, but I still don't get my error (or can't detect it).

Upvotes: 0

Views: 1037

Answers (1)

gaFF
gaFF

Reputation: 757

You have circular depencies between all your modules. I think no module can be fully parsed, and the names inside the modules are never declared in their scope.

EDIT: When Python enters the first file, it tries to read it. To simplify, you have 2 cases: Python find an instruction and executes it (e.g. print("spam")), or Python find a definition (e.g. def f():). A definition means a new name will be created and added to the scope it was found, usually for class and function the module scope. Definitions of a module are available to other modules once the original is fully read.

But when it encounters an import, Python switch to the imported file, because an import means some names necessary to understand the original file will be found in the imported file. When you have circular depencies, the core of the file is never read, you are kept inside an import loop, and the definition of class, function... are never available to the other modules.

First you have to clean dependencies: Roll cannot import Module_Frame when Module_Frame import Roll. If the class Games is needed by all the other modules, it can not import any of the other modules. But it's hard to propose a file structure without the full knowledge of what you want.

Then using:

import Module_Frame
class tenth_Frame(Module_Frame.Frame):
     pass

or

from Module_Frame import Frame
class tenth_Frame(Frame):
     pass

should work.

Upvotes: 1

Related Questions