Python: Class to set properties, good idea?

Hi,

In order to get things easier, I had the idea to set up a class with properties.

Would that be a good idea or is there a better method? Thanks in advance.

Here is a simple example:

class Movement:
    
    walk_speed = 5.0
    
    run_speed = 8.0
    


movement = Movement() #init class


def Walk():
    
    movement.walk_speed #get data from class
    

def Run():
    
    movement.run_speed #get data from class

I would be more tempted to make a ‘Player.py’ class and define the movement variables and functions within that. Makes more sense to me to do it that way. I think you will find that you are going to end up with a lot more variables than that, so it would make sense just to make all those variables of a Player class, to keep it more object orientated.

Hey thanks a lot Klauser for that hint.

So you mean sth like that:

class Player:
    
    walk_speed = 0.0
    
    
    
    def setWalkSpeed(self, walk_speed):
        
        self.walk_speed = walk_speed
        
    
    def getWalkSpeed(self, walk_speed):
        
        return self.walk_speed
        
        
     

#create Object
Player = Player()

#set Objects property
Player.setWalkSpeed(5.0)





#this comes from a new module script
def Walk(cont):
   
   #do sth with the Player speed
   speed = Player.getWalkSpeed     

That concept is correct.
However, be aware of the following:
Any muteable types - datatypes with values that can be changed within their structure without breaking the object reference - will modify directly the class value, not the instance (unless you define it as an instance variable)

Hey thanks Agoose77.

That concept is correct.

Huh, now I am so relieved

Any muteable types - datatypes with values that can be changed within their structure without breaking the object reference - will modify directly the class value, not the instance (unless you define it as an instance variable)

I don’t understand that, sorry for that. But can you explain that a bit non-expert like, please.

A word of warning: This concept creates a singleton. This means you can have EXACTLY one object with this file.

I suggest to store the object instance in a property:


def MyClass():
  def __init__(self, owner):
    self.owner = owner

  def doSomething(self):
    print("I do something and I belong to", self.owner)

def setup(cont):
  ''' Setup a myInstance on the calling game object.'''
  cont.owner["myInstance"] = MyClass(cont.owner)

def doSomeThing(cont):
  ''' must be called by a "myInstance" owner '''
  if not allPositive(cont.sensors):
    return
  myInstance = cont.owner["myInstance"]
  myInstance.doSomething()

def doSomethingForAll(cont):
  ''' can be called by a "manager" '''
  for gameObject in bge.logic.getCurrentScene().objects:
    myInstance = gameObject.get("myInstance")
    if myInstance is None:
      continue
    myInstance.doSomething()
      

Be aware to call the according entry points by the applicable game objects.
This method allows you to use this code with any number of game objects.
You can even use different classes.

This method is pretty good if you want to avoid a lot of internal properties (internal property = Non-GUI property) as you need only one per class instance.
This method is pretty bad if you use properties as interface to other objects.
This method still supports properties as the owning game object is still available.

I believe that what agoose77 means is that you’re setting class properties in your second and first post, rather than object properties. Example:



class Bike:

     speed = 1.0

Bike.speed = 5.0


That modifies the bike class’s speed value.



class Bike:

     def __init__(self):

          self.speed = 1.0

motorcycle = Bike()
bigwheel = Bike()

motorcycle.speed = 5.0
bigwheel.speed = 0.5

That modifies the instances’ speed values. Just putting the variables in the class makes them accessible, but class variables, rather than instance variables.

Muteable types are related to this, but not directly.

When a class is instatiated, with the init constructor, it calls the class new (from base type object)
This ends up mapping all class attributes to the instance.

With any data types that don’t have mutability, when you change their value, it creates a new instance of that type.

For example, when setting an integer, it creates a new integer instance, and the old instance is sent to garbage collection:


a = 1
a = 2 # New instance

Whereas, some data types can be modified in place, and their values changed without destruction:


a = {}

a["James"] = 34

From Python.org:

The value of some objects can change. Objects whose value can change are said to be mutable; objects whose value is unchangeable once they are created are called immutable. (The value of an immutable container object that contains a reference to a mutable object can change when the latter’s value is changed; however the container is still considered immutable, because the collection of objects it contains cannot be changed. So, immutability is not strictly the same as having an unchangeable value, it is more subtle.) An object’s mutability is determined by its type; for instance, numbers, strings and tuples are immutable, while dictionaries and lists are mutable.

A word of warning: This concept creates a singleton. This means you can have EXACTLY one object with this file.
Oh thanks that is true and therefore might be useless.

I really like examples so here is it with a singleton:
player_testClass.blend (481 KB)
press space at start and after second player rotates. So you just get the changed rotation. No way to get each rotation indivually.

This method is pretty bad if you use properties as interface to other objects.
So creating a Class for the Player it not really a good thing to do. Better use internal properties??

@SolarLune and @Agoose77

Thanks now I think I got it.:yes:

Ok I redesigned my script.

The goal was to have as many players as you want but each with indivdually settings.

Here is my example.
multiple_player.blend (483 KB)

Now I am intersted if there is a better way or how you would solve that task?

Thanks in advance

A:
Switch to module mode otherwise you get a bunch of files without organization.

B:
It looks like you want to inject the logic from another object (a manager). This is possible and makes sense e.g. on loading data from a file. But this makes it hard as the manager needs to know the implementation of each involved object.

You can simply search for objects with a specific property. These are the objects the manager is managing (e.g. property “player”). As far as I see you do that already.
But I do not really see the benefits of using a class instance to apply data to the managed game objects. A dictionary or list can keep the initial data as well. BTW. This is how SaveLoad systems work.


settings = [
 {"player":1, "walk_speed":5.0, "run_speed":10.0}
,{"player":2, "walk_speed":2.0, "run_speed":4.0}
]

It looks like you do not use the instances of Player any further.

C:
When working with group instances you can use the LinkLib. It establishes a connection between instantiating object (pivot) and one object of the group instance (base). This enables you to provide parameters as properties at the instantiating object (e.g. walk_speed, run_speed).
The usage is a bit cumbersome but not too complex. You can check the MouseOrbiter, FreeViewControl, VisualVehicleWrapper. They use the LinkLib too.

I hope it helps

@MarcoIT
Thanks a lot for your help and example. But I need dublicated groups.

@Monster
Thanks a lot for clarification.

To point A:
I will, this was just a fast example.

To point B:

A dictionary or list can keep the initial data as well.
This is the way to go. Thanks

To point C:
Till now, I haven’t needed to use LinkLib. Perhaps, I did something wrong as I work with groups most of the time.:eyebrowlift2:

someone has one example where the use of class become powerfull/fast(or more easy) ?
in a blend?

better than a normal module