0

I have an instance of a class that i set the value to 'self.world' inside a class named 'zeus' inside a module named 'Greek_gods'. and i have another class names 'World' inside a module name 'World'.

How can i tell zeus to go to 'World' and get the instance self.world?

#module named World
class World():

    def __init__(self):
        self.world = Atlas()


#module named Greek_gods
class zeus():

    def __init__(self)
user1082764
  • 1,973
  • 9
  • 26
  • 40
  • does instantiating a class inside itself work, seems like that would be infinite? – dm03514 Jun 08 '12 at 16:55
  • @dm03514: no, it will result in an infinite loop - in order to construct a World, you first have to construct a World. – Hugh Bothwell Jun 08 '12 at 16:56
  • 1
    Your going to get a RuntimeError by infinitely instantiating `World()`. What exactly are you hoping to accomplish? – Joel Cornett Jun 08 '12 at 16:56
  • It was a mistype. I meant to instantiate Atlas not World inside itself – user1082764 Jun 08 '12 at 16:57
  • 1
    Seems like you'd have to instantiate `World()` before you can access it's instance variables. Where do you create an instance of `World()`? – Joel Cornett Jun 08 '12 at 16:57
  • 1
    Seems to me that even if you could tell `zeus` to go mess around with `World`'s variables, that'd be a pretty bad idea since it breaks encapsulation. Better, i think, would have `zeus`'s constructor accept a `World`, or better yet an `Atlas` (since it really doesn't need a whole `World`). – cHao Jun 08 '12 at 16:58
  • See also [this question](http://stackoverflow.com/q/10942831/1290420) by @user1082764 -- it is courteous to cross-reference related/identical questions. – daedalus Jun 08 '12 at 17:36

4 Answers4

2

You can't, because you cannot know the world instance to be added in Zeus at the moment you create Zeus.

However, you can pass an instance of World for Zeus. There are various ways to do it:

  • Pass World as a parameter to the constructor:

    #module named greek_gods
    class Zeus(object):
        def __init__(self, world):
            self.world = Atlas()
    
    world = World()
    zeus = Zeus(world)
    
  • You can make World to create Zeus:

    #module named World
    class World(object):
        def __init__(self, world):
            self.world = Atlas()
        def create_zeus(self):
            zeus = Zeus()      # It would be better to pass it as a constructor 
            zeus.world = world # parameter but let us leave it simple
    
     # Using your classes:
     world = World()
     zeus = World.create_zeus()
    
  • You can create one special instance of World in the world module:

    #module named World
    class World(object):
        def __init__(self):
            self.world = Atlas()
    greek_world = World()
    
    
    #module named Greek_gods
    import world
    class Zeus(object):
        def __init__(self):
            self.world = world.greek_world
    

I would recommend to use the second solution; after that, the first one. The third one, however, can be very useful, too, specially if, by default, you need just one world in your application (the so-called singletons).

brandizzi
  • 26,083
  • 8
  • 103
  • 158
1
# module World
class World(object):
    def __init__(self, name):
        self.name = name
        self.gods_here = set()

    def leave(self, god):
        self.gods_here.remove(god)
        return True

    def enter(self, god):
        self.gods_here.add(god)
        return True

# module Greek_Gods
class God(object):
    def __init__(self, name, world=None):
        self.name = name
        self.world = None
        self.go_to_world(world)

    def go_to_world(self, world):
        if self.world is not None:
            self.world.leave(self)
        if world is not None:
            if world.enter(self):
                self.world = world
        else:
            self.world = None

earth = World("Earth")
mars = World("Mars")

zeus = God("Zeus", mars)
zeus.go_to_world(earth)
Hugh Bothwell
  • 55,315
  • 8
  • 84
  • 99
1

It does exactly what you asked for - it goes to World module and takes World's instance's world attribute:

#module named World
class World():
    def __init__(self):
        self.world = Atlas()


#module named Greek_gods
from World import World

class zeus():    
    def __init__(self)
        self.world = World().world

Although it may be done cleaner, if you could tell us what is the reason to do so. You can even shorten the code, if you assign Atlas() to the class'es property world. It will be shorter to reference it and cleaner, but will work almost the same.

Tadeck
  • 132,510
  • 28
  • 152
  • 198
0

It looks like you want to use a single instance of a World class across several modules, which you can do easily by creating an instance of the World class at the top level of your World module, like this:

#module named World
class World():
    def __init__(self):
        self.world = Atlas()

world = World()

Now when you import World in any of your other modules, you can use World.world as the only instance of your World class. This gets a little confusing, because World.world.world is now the instance of Atlas that the World class creates, I would strongly suggest renaming something there.

Here is how your Greek_gods module might look:

#module named Greek_gods
import World

class zeus():
    world = World.world.world

Note that instead of putting world into the initializer for the zeus class, I made it a class attribute. This is because it looks like you want to share this Atlas instance (which for some reason is called world) among all zeus instances. For an example of how this would look, check out the following code (which you could put into your Greek_gods module to test):

z1 = zeus()
z2 = zeus()
assert World.world.world is z1.world is z2.world 
Andrew Clark
  • 202,379
  • 35
  • 273
  • 306