0

I am working with python at the moment and wonder about something. I'm not too good with object programming, as I've always coded with imperative languages (C mostly).

So I'm asking myself.

Say I have an instance of class_1 called c1, declared this way:

c1 = class_1(bla bla bla...)

Say c1 has a heck lot of variable declarations inside, like

self.x = ...
self.y = ...
self.z = ...
#etc etc

Now, I have an instance of type class_2, called c2. Say c2 is declared INSIDE c1's init() function, like that

c2 = class_2(bla bla bla...)

Now, I wonder how I could... acces the objects of c1 from within c2?

Some could say I could make class_2 inherit from class_1. That's not exactly what I want in fact. The reason is that, class_1 should include in a logical way objects that are of type class_2, but class_2 needs to access variables from class_1! If I would make class_2 inherit from class_1, I would always have to... declare class_2 objects in the external (to the classes) code. I want to work, in the external code, with class_1 objects. How can I reasonably do that? Starting to be a nightmare...

Thanks!

EDITED:

The context in which I use it... I have, as an assignment, to write a small space video game. I have to calculate trajectories in space. I also have a map. Some parameters such as acceleration, rotation speed, etc... Are specific to the 'map' : i.e. we design a map with obstacles and all, but depending on the map, the some physics constant vary. I also have a 'physcis' class to handle different calculations related to the trajectory, position upating, etc etc. So I just want to be able to use the many many many instances of different objects which are contained in the 'map' class, so that I can use these variables inside the physics class! Is it legit? Thanks!

6
  • 1
    The simplest way is to pass the self from the __init__ as an argument to class_2. Also, your terminology seems a bit off. If class_1 is your class, c1 is not a class, it is an instance. Commented Nov 30, 2013 at 8:25
  • c1 and c2 look like instances here, not classes. Commented Nov 30, 2013 at 8:26
  • yes, sorry, c2 and c1 are instances of their respectives class_2 and class_1 types, apologies Commented Nov 30, 2013 at 8:30
  • Can you describe a use case for this? If you describe how you plan to use these objects, we'd be better able to understand the relations between them and better able to suggest solutions. Commented Nov 30, 2013 at 8:31
  • Mainly, I want to know whether this is a has-a relationship (for example, class_1 is BinaryTree, class_2 is Node, and BinaryTrees contain Nodes) or an is-a relationship (for example, class_1 is Animal, class_2 is Dog, and you want to decide whether to return a Cat, Dog, or DancingWalrus without requiring the call site to explicitly call the Dog constructor). Commented Nov 30, 2013 at 8:35

2 Answers 2

2

From what I can gather from your question, each class_2 is related to a particular class_1. I'll call that class_1 the parent object.

You want to be instantiating a class_2 from within the parent, so something like

class Class_1(object):
    def __init__(self):
        self.x = 1 # Your instance variables here
        self.y = 2
        self.class_2_instance = Class_2()

class Class_2(object):
    def __init__(self):
        pass

is what you want. But you need to access stuff from the parent inside class_2, right?

Simply pass the parent into class_2:

class Class_1(object):
    def __init__(self):
        self.x = 1 # Your instance variables here
        self.y = 2
        self.class_2_instance = Class_2(self)

class Class_2(object):
    def __init__(self, class_1_instance):
        self.class_1_instance = class_1_instance

And now you can, from within class_2, access class_1's variables.

print(self.class_1_instance.x) # prints 1

edit: You've clarified something about your question in the comments since I started writing this response, so now that I know what c1 and c2 are, I can show you how you would use the code I've written here:

c1 = Class_1()

c1 will now have an instance of Class_2 contained within it. That instance will be able to access all of the properties of c1.

Sign up to request clarification or add additional context in comments.

1 Comment

Have chosen your answer, since you were the first to recommend this strategy. Thanks a lot!
1

One trick is to pass a parent parameter into the class2.__init__ and keep it e.g.:

class class2:
    def __init__(self, parent, ):
        """ Create an instance of class2 saving the parent """
        # You might wish to assert that parent is type class1 here
        self.parent = parent

This will let you access class1 members from within class2 as self.parent.member which seems to be what you need.

Even if you can define a class within a class I would urge you not to - it would lead to unclear code and I suspect would actually have more of an overhead than you might expect.

You can define class2 in the same file as class1 and class1 can either inherit from it or simply have members of the type class2 but if you call your class2 an underscored name such as _class2_ then by convention you are making them private to the scope in which they are defined, in this case the file where they are defined, (N.B. In python private is a convention - not enforced - more a gentlemen's agreement with the warning that private members may be modified/removed at any new version).

Note that defining a class is not the same as creating a class instance.

Just to see if it could be done I tried:

Python 2.7.5+ (default, Sep 19 2013, 13:48:49) 
[GCC 4.8.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class A:
...     class B:
...          def __init__(self):
...              self.b = 3
...     def __init__(self):
...         self.b = B()
...         self.a = 2
... 
>>> a = A()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in __init__
NameError: global name 'B' is not defined

This is because the rest of class A does not exist until init is finished, so class B needs to be defined inside the init before it is used -

>>> class A:
...     def __init__(self):
...         class B:
...             def __init__(self):
...                 self.b = 3
...         self.a = 2
...         self.b = B()
... 
>>> a=A()
>>> a.b.b
3
>>> 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.