Michael Kirsch
Michael Kirsch

Reputation: 19

Python: Access to other Classes Objects

I have a question regarding the classes in python3. In my programm i have a "main" class that is getting started first and sets some parameters that are needed for the other parts of the programm. But now my other classes need some objects of the main class. How can i use the objects of the main class without initialising the main class everytime the subclass needs the object ? I looked into python inheritance but maybe i didnt understand it correctly

class Chunk(main.Main):
    def __init__(self,pos_in_world_x,pos_in_world_y):
        #self.chunksize =  settings.blocks_per_chunk
        self.prog = main.Main.prog
        self.ctx = main.Main.ctx

this is my code for the subclass

Upvotes: 1

Views: 72

Answers (3)

Ovaflo
Ovaflo

Reputation: 684

It is actually difficult to hide information in Python, so here are a few options which don't require inheritance (see jpp's answer for the inheritance option). In general, the code is easier to understand when you pass information explicitly (option 1 below, or inheritance), but there may be cases where you'd prefer the other options.

Option 1: The needed info can simply be passed as additional arguments to Chunk's __init__ (either by passing the prog and ctx values themselves, or by passing the Main class or its instance - depending on whether the needed info is stored as class or instance variables). Here's an example of passing Main as an argument:

class Main():
    prog = 1
    ctx = 2
    def __init__(self):
        pass

class Chunk():
    def __init__(self, pos_in_world_x, pos_in_world_y, M):
        #self.chunksize =  settings.blocks_per_chunk
        self.prog = M.prog
        self.ctx = M.ctx

c = Chunk(3, 4, Main)
print(c.prog)  # 1
print(c.ctx)   # 2

Option 2: Chunk can access Main's class variables directly:

class Main():
    prog = 1
    ctx = 2
    def __init__(self):
        pass

class Chunk():
    def __init__(self, pos_in_world_x, pos_in_world_y):
        #self.chunksize =  settings.blocks_per_chunk
        self.prog = Main.prog
        self.ctx = Main.ctx

c = Chunk(3, 4)
print(c.prog)  # 1
print(c.ctx)   # 2

Option 3: Chunk can access the instance variables of the Main instance directly (Main needs to be instantiated before Chunk is instantiated):

class Main():
    def __init__(self):
        self.prog = 1
        self.ctx = 2

class Chunk():
    def __init__(self, pos_in_world_x, pos_in_world_y):
        #self.chunksize =  settings.blocks_per_chunk
        self.prog = m.prog
        self.ctx = m.ctx

m = Main()
c = Chunk(3, 4)
print(c.prog)  # 1
print(c.ctx)   # 2

Upvotes: 0

Dan D.
Dan D.

Reputation: 74645

You need a super __init__ call in your subclass and if you have that you only need to do:

class Chunk(main.Main):
    def __init__(self,pos_in_world_x,pos_in_world_y):
        super().__init__()
        #self.chunksize =  settings.blocks_per_chunk

Both of the assignments are done by Main's __init__.

But I think that Chunk has not an is-a but rather a has-a relation with Main so Main should actually be an argument rather than a super class:

class Chunk(object):
    def __init__(self, main, pos_in_world_x,pos_in_world_y):
        #self.chunksize =  settings.blocks_per_chunk
        self.prog = main.prog
        self.ctx = main.ctx

Any one that creates a Chunk must pass a Main instance.

Upvotes: 0

jpp
jpp

Reputation: 164633

You can use class variables:

class Main():
    prog = 1
    ctx = 2
    def __init__(self):
        pass

class Chunk(Main):
    def __init__(self, pos_in_world_x, pos_in_world_y):
        self.prog = Main.prog
        self.ctx = Main.ctx

a = Chunk(3, 4)
print(a.prog)  # 1
print(a.ctx)   # 2

If you can't change Main to move your definitions outside __init__, then what you're asking for is impossible. If your variable is defined in __init__, you can't access it before calling __init__, i.e. initialising the class. You can't get round this.

Upvotes: 1

Related Questions