Class problem - double-side access

Hi! I am looking for a way to access classes in this approach:



class 1:
    def __init__(self):
        pass
    c2 = 2()
    self.thing = c2.getThing()
    self.thing *= 5
    def getThingy(self):
        return self.thing

class 2:
    def __init__(self):
        pass
    c1 = 1()
    def getThing(self):
        return self.thingy
    self.thingy = c1.getThingy()

You shouldn’t tell me why I need this. Just tell me how to get it working that class 1 can access class’s 2 functions and class 2 can access class’s 1 functions.

Thanks!:slight_smile:

You shouldn’t tell me why I need this

Sorry, but if people give advice it should usually be well-considered, rather than careless.

Your psuedo code wouldn’t work, (apart from the fact that you cant have numbers as class names) because the class body is executed with the module (so in class 1 where it executes c2=2(), c2 wouldn’t exist yet). Also, that’s a horrible circular reference in your example. You should show a better example with real code and explain why ​you need this.

Well… Hm… Yeah… M…

OK! The .blend:

http://www.pasteall.org/blend/39079

Yikes, you’re defining instance-data in the class body (self doesn’t exist there). I suggest you practice using classes with simpler tutorials. It’s more pythonic to use properties (@property) instead of getter functions (getX), but here you don’t need either, just use the attribute itself.
Don’t instantiate classes in the class body unless you explicitly want that - the resulting instance is shared between all instances of the containing class body (E.g wt1= weight_transfer(); wt2=weight_transfer(); print(wt1.wheels is wt2.wheels); >>True)

I just quote this part couse your example shows that you clarely don’t know what you’re doing (makes sense, since you’ve asked).

First as agoose77 said, don’t name things with numers, use some style (google’s good). Example ClassName1 and variable_name1. Or just Foo1, Foo2, etc…

Then, there is nothing bad with circular dependences (I can hear an horde getting furious at me now). Well if they are “dependences” then it’s very bad, but if they are just acces then there is no problem. Example:


A.py
import B
class A:def __init__(self):

[INDENT=2]self.B = B(self)
self.val = B.getValB()
[/INDENT]

def getValA(self):

[INDENT=2]return "Hello!"
[/INDENT]

B.py
#Do not make "import A" here or you'll have a circular dependence.
class B:
def __init__(self, A):

[INDENT=2]self.A = A
self.val = A.getValA()
[/INDENT]

def getValB(self):

[INDENT=2]return self.A.getValA()

[/INDENT]

So yeah, now you have B inside A but you can still acces A from B. From outsaide A you can still have acces directly to B with B = A.B, however now you have the problem that B needs an extra argument on initialization. You can solve this as follows but you will lose the ability to use A on B initialization:


A.py
import B
class A:def __init__(self):

[INDENT=2]self.B = B()
self.B.A = self
self.val = B.getValB()
[/INDENT]

def getValA(self):

[INDENT=2]return "Hello!"
[/INDENT]

B.py
#Do not make "import A" here or you'll have a circular dependence.
class B:
def __init__(self):

[INDENT=2]self.A = None
#self.val = A.getValA() #We can't acces A yet!
[/INDENT]

def getValB(self):

[INDENT=2]return self.A.getValA()

[/INDENT]

We can solve this using a static member, but usually going this far is not nesscesary:


A.py
import B
class A:def __init__(self):
[INDENT=2]B.A = self
[/INDENT]
[INDENT=2]self.B = B()
self.val = B.getValB()
[/INDENT]

def getValA(self):

[INDENT=2]return "Hello!"
[/INDENT]

B.py
#Do not make "import A" here or you'll have a circular dependence.
class B:A = None

def __init__(self):

[INDENT=2]self.A = B.A
self.val = self.A.getValA()
[/INDENT]

def getValB(self):

[INDENT=2]return self.A.getValA()

[/INDENT]

Try to play with this, rewrite it several times, make prints, make new methods, new attributes…


class Character:

    """Class that represents a character"""

    def __init__(self, name):

        """class constructor. Class attributes have to be initialized here"""

        self.name = name
        self.age = 15

    def getAttributes(self):
        """converts attributes into a string chain"""

        return "{0} {1}".format(self.name, self.age)
    
    def getAge(self):

        return self.age

    def setAge(self, newAge):

        self.age = newAge


class SpecialAgent(Character):

    """Class that represents a special agent.
    This class inherits from Character class"""
    
    def __init__(self, name, agentIdentification):

        """A special agent is defined by its name and its agentIdentification"""

        # We explicitely call the Character class constructor to access its attributes and its methods   (functions):
        
        Character.__init__(self, name)
        self.agentIdentification = agentIdentification

    def getSpecialAgentAttributes(self):
        """converts SpecialAgentAttributes into a string chain"""

        return "{0} {1} {2}".format(self.name, self.age, self.agentIdentification)
    
adrians = SpecialAgent("adriansnetlis", 10245)


print(adrians.getSpecialAgentAttributes())
print(adrians.getAttributes())
print(adrians.age)
adrians.age = 16
print(adrians.age)
print(adrians.getSpecialAgentAttributes())
print(adrians.getAttributes())
adrians.setAge(17)
print(adrians.getAge())

EDIT: Sorry it doesn’t answer your question :o. I was a general answer about how to deal with classes.

Since you’ve express not wanting to explain why you’re trying to do this, I’m perfectly fine with giving you enough rope to hang yourself with. Class attributes can be created after the class definition, so you can simply wait until after both classes have been defined to give them attributes pointing to instances of each other.


class A:
    pass

class B:
    pass

A.b = B()
B.a = A()

Though at that point you may as well make your instances of A and B globals.

OK! So much answers, I don’t understand anything any more now. Mobious, will your method work fine and not output errors like “self.b is not defined!”?

As long as you only try to access self.a or self.b inside function definitions instead of at the class definition level, it will work fine.

Oh… OK! I will try it, thanks!:slight_smile:

http://pasteall.org/blend/39080
A fixed version:)

While adding attributes from outside the class definition is possible, it is no good style.

I recommend to define attributes in the init constructor. This way it is guarantied to be present in the final object.


class A():
    def __init__(self, b):
        self.b = b

class B():
   def __init__(self, a):
       self.a = a


This design has a big issue. It creates a circle dependency. You can’t create one object without the other. But you can create only one object at the time.

So we need to set the reference to a/b at a later time:


class A():
    def __init__(self):
        self.b = None

class B():
   def __init__(self):
       self.a = None

a = A()
b = B()

a.b = b
b.a = a

This guaranties the attributes are always there, but they can contain None.

A middle way would be to provide both options:


class A():
    def __init__(self, b=None):
        self.b = b

class B():
   def __init__(self, a=None):
       self.a = a

a = A()
b = B(a)

a.b = b # close the circle

If you want to ensure to create completely setup objects and the objects can’t do it by themselves, you can use a factory function:


def createAB():
    a = A()
    b = B(a)
    a.b = b
    return a,b

a,b = createAB()

Ensure always to use this function when you want to create a and b.

If you want to create instances of other classes in a class you get a factory class:


def ABFactory():
    def create(self):
        a = A()
        b = B(a)
        a.b = a
        return a,b        

factory = ABFactory()
a,b = factory.create()

Why creating a class to do such do that? I know you want have a car project. Now imagine you want to create objects regarding different kind of cars. So you can create factories that can create a certain car with all it’s sub-components and relationships.

Finally you get a car, regardless what kind of car:


class Vehicle:
   ...
class Truck(Vehicle):
  ...
class Roadstar(Vehicle):
  ...
class Bike(Vehicle):
  ...

class TrackFactory():
   def create(self):
      ...
      return track

class RoadstarFactory():
    def create(self):
        ...
        return roadstar

class BikeFaktory():
    def create(self).
        ...
        return bike


By using any of the factories you always get a Vehicle, but a specific one.


def buildMyVehicle(factory):
    vehicle = factory.create()
    ower["myVehicle"] = vehicle

def driveForward():
   owner["myVehicle"].drive(0.3)

For example you could have selected a specific factory at the vehicle selection menu. So the player choose to create a Truck, so you setup the TruckFactory. When entering the Track-level, you do not care what factory it is, you tell it to create a vehicle and you get one.

What is the difference between Factory class an Factory function? What the above example doe not show is that you can give the factory certain setup attributes (e.g. number of wheels, engine class) it should use. If you use the Factory function you need to provide that as parameter, which does not always fit.


class TrackFactory():
   def __init__(self, numberOfWheels, engine):
       self.numberOfWheels = numberOfWheels
       self.engine = engine

   def create(self):
       truck = Truck()
       for wheel in range(self.numberOfWheels):
           self.createWheel(truck)
       truck.engine = engine
       engine.vehicle = truck
       return truck

threeAxisTruckFactory = TrackFactory(6, DieselEngine())
twoAxisTruckFactory = TrackFactory(4, DieselEngine())

One the other side a bike always has two wheels. So there is no need to tell the number:


class BikeFactory():
    def __init__(self, engine):
      self.numberOfWheels = 2
      self.engine = engine
...

I hope this does not confuse you too much

Thank you. However, sdgeoff promised me a little, but advanced explanation of class system so I will rewrite it. However, could you point me to a good car suspension tutorial or show me how it is setup in Blender wrapper(because it’s suspension is fine, the thing wrong with it is the cornering)?

I tend to set up a container, like a Car() which contains components like Wheel(car) with a reference to the parent container. Car just runs Wheel.update() and wheel gets its info from the car like speed and performs its functions like rotate() as part of the update function. Then subclasses like Bike() can just rewrite the container and reuse the components.

Sdgeoff gave me a pretty interesting tutorial out there:)

For reference, here’s what I gave Adriansnetlis. It isn’t perfect, and any suggestions on it are appreciated.

Attachments

Class structure study.pdf (208 KB)

Thanks sdfgeoff!!

Object oriented programming (OOP) is a powerful programming concept that
allows entities to have actions, to own other entities and to have properties. For
example a car will own an engine (another entity), it has a quantity of fuel (a
property) and it can start its engine (an action).
Because entities can own other entities, we need to be able to structure our
information flow to keep it as hierarchical as possible. An engine is part of a
car, it does not own a car, this needs to be reflected in our class structure. If
an owned class required information from it’s owner, it’s owner should tell it
(eg the engine can only run when there is fuel. How do we tell it when there is
fuel?).

maybe i’m not a good “finder” but to me seem extremely hard found examples understandable of classes.
game-oriented. (not “hello world” oriented)

so , the car (obj) know all , while the other “pieces” know nothing?
ie, the well1 not know whell2 (this pretty obvious)
well1 not know car ?
engine not know car ?
anyone know the car ?
you confirm?

if so, is a special case for the car ,(maybe require high centralization) or is a “pattern” (one root and many “pieces” managed from the root directly where each piece know nothing)

thanks

PS: i’m curios also to see the “impact” python object / game object :eek: :cool:

It isn’t perfect, and any suggestions on it are appreciated.

is written very well about “how structure the class” (but i not read so well the english)
the last part is not clear, in the structure seem that the suspensions replace the whells? so the car not know more the whells?
and what do PID…is omissed(and probably too complex)
until 2.2 is good

so , the car (obj) know all , while the other “pieces” know nothing?
ie, the well1 not know whell2 (this pretty obvious)
well1 not know car ?
engine not know car ?
anyone know the car ?
you confirm?

Every class knows what is below it (and occasionally what is above it)
So the car knows it has a transmission, but doesn’t know it has a gearbox. The transmission knows it has a gearbox, but doesn’t know that the car has wheels.

Sometimes things do have access to their owners, but generally this just leads to confusion. (you pass the owner into the class when you initalize it, eg: def init(self, owner, data1, data2) )

if so, is a special case for the car ,(maybe require high centralization) or is a “pattern” (one root and many “pieces” managed from the root directly where each piece know nothing)

Ideally it should be a heirachy, with each part only knowing the ones below. Sometimes relationships get a little distorted. One example is when the suspension is brought in. Do we have:
Car -> Suspension -> Wheels (suspension owns wheels)
because the wheels are attached to the suspension which are attached to the car, or do we have:
Car -> Suspension
`-----> wheels (car owns wheels)
Because when one thinks about a car, you say “a car has wheels”?

There is no correct answer in many cases, and it is up to the programmer to pick one and run with it.

There are other cases, such as guns in FPS’s, you need a list of guns the player has, and a the gun the player is currently holding. But again, the guns don’t know about each other, and the player doesn’t directly know about the ammo for each gun: he has to query the gun for that.

PS: i’m curios also to see the “impact” python object / game object

Sorry, I don’t understand this sentence. Are you meaning mutating a game object into a custom python class?

and what do PID…is omissed(and probably too complex)

Yup, PID is another whole topic, but I’ll brush on it lightly now, and perhaps a little more in a week when I next have internet access (so queue up the questions).
P stands for proportional, it means that the further an object is from where we want it to be, the more force we apply. Think of a spring.
I stands for Integral. It is a combination of distance away and time. The longer the object is not where it should be, the bigger it is.
D stands for derivative. It is how fast the object is approching it’s correct position. It acts like damper.
You then add all the elements together and you have a PID controller. If you tune it right you can control any second order system without having to model it accurately.

So for car suspension, you tend to have PD control: a spring and a damper. Integral has no easy physical analog, but is used to correct ‘steady state error’ in non-ideal systems.

I have a standard PID system I use that I’ve written in C, C++, Python, Javascript … Write a class for them, and you’ll use it everywhere.

You have already used a PID controller in BGE: the servo motion actuator. Ever wonders what the three boxes at the bottom labeled ‘proportional gain’, ‘integral gain’ and ‘derivative gain’ were? Well, now you know.

It looks like people are wanting me to write a small book. I’m actually relatively keen for this, as there are a lot of programming topics I want to cover:

  • Vectors and matrices
  • PID
  • Class Structure
  • Code Structure and modularity
  • Scheduling
  • AI

Can anyone think of any common programming topics they’d like touched on?

That idea is awesome!:slight_smile: Hm… Maybe a topic releated to optimisation, speed gain and more control over scripts? Where it is explained how to make scripts run faster, look better, get easier to navigate and get easier to add stuff in. Something like a full-range optimization. I may need this…

Sometimes things do have access to their owners, but generally this just leads to confusion. (you pass the owner into the class when you initialize it, eg: def init(self, owner, data1, data2) )

Personally I think that not having access to the owner causes more confusion, or anyway requires more top down management.
If you make each component more autonomous it allows easier reuse of components and less custom code.

You might have a car with ten wheels and 3 engines for example, and the car just does:

for engine in self.engines:
    engine.update()

for wheel in self.wheels:
     wheel.update()

And each wheel does:


driving_wheels = [wheel for wheel in owner.wheels if wheel.driven and wheel.active]
self.torque = owner.engine_torque / len(driving_wheels)
    self.apply_torque()

In this way it doesn’t matter how many wheels you have, or if they are driven or not (set that as an initiation argument) or even if they are attached to the vehicle or not (maybe they broke off and are laying in the road…). Likewise it doesn’t matter the type or size of the engine, since each component just does its job and feeds back info to the container.

Of course you have to make some assumptions about the container from within the components (like that the wheels are attached to a car which has a self.wheels attribute) but that’s no different from making assumptions about the components from within the container (assuming that all wheels have a self.apply_torque() method). As long as no wheels are attached to a donkey, or bananas are attached to a car, then there’s nothing to worry about.

I like to have a chain of reference all the way up to the main game loop, but that’s just my preference. Since I might need to get some data from further up the chain.

An example might be that I want to find out who fired the Bullet() which killed an NPC(). I can check the owner of the bullet, which is a Gun(), and that gun has an owner, another NPC(). The shooting NPC has a self.team attribute and I can check the team.name, so I can find the team which killed the first NPC, and award victory points accordingly.

Note, I would use:

bullet.gun.shooter.team.victory_points += self.vp_value

rather than:

bullet.owner.owner.owner.victory_points += self.vp_value

The other option is to pass an argument down through the hierarchy each time a class is initiated, so that every bullet, gun and shooter has a self.team attribute which it passes down to its children, even though it might never use the attribute itself.

I suppose one reason I like the ownership chain idea is it makes developing game prototypes quicker as you don’t have to do so much forward planning, and you don’t have to go back and edit stuff you’ve already written. You can also be more adventurous, try something out and if you don’t like it, just go back and scrub out that one like of code, rather than going and finding every reference to that chain in every class you’ve just rewritten.