Search Results

Thursday, April 12, 2012

Python Tip - Classes

Hey. So, I thought I would write up a little something on classes in Python.
Classes are particularly useful because they represent objects in code. If you're familiar with object  oriented programming, then you already know the concept behind classes and objects in Python, but if not, it's fairly simple to learn. Let's take a look at an example.

Say you have a bicycle. Your bicycle is an object, right? What kind of object is it? Well, it's a kind of bicycle. Your bike, and all of the other bikes of the same model, were made from a prototype - a 'mold'. So, if we were to translate that to code, the prototype, or mold, would be the class, and the bike would be the object. Objects are derived from classes.

  1. class Bike():
  2.    
  3.     __init__(self): # Lay down some initial bike stats
  4.        
  5.         self.color = 'White'
  6.         self.wheels = 2
  7.         self.motor = False
  8. yourbike = Bike() # Create a new Bike object

In the example above, we define a Bike class, define its color, number of wheels, and whether or not it has a motor, and then create a new object from the class.

In line 1, we start with the class keyword - this tells Python that we're starting a new class. Notice that we put a parentheses after the class name, and then put a colon at the end. Those parentheses serve a special purpose that we'll cover later.

In line 3, we define a function called __init__(). Note that this function is named "__init__" because Python specially reserves that function in a class for initialization. Basically, if we create an object from a class, Python will call the __init__() function if it exists. Notice that there's also the self argument.

The self argument is special in classes because of two reasons.

1. The self argument is the first argument of any function created in a class.
2. The self argument refers to the object, and so can be used to store and access variables.

In the above example, we use the self variable to store information in the class object - we set the color to "White", the number of wheels to 2, and whether the bike has a motor to False. If you recall, Python is a very dynamic language - we don't have to type anything special to initialize variables. If they don't exist, they're created when we try to set them.

Finally, in line 9, we create an object from the Bike class named yourbike. We set a variable to the class name, plus parentheses - this tells Python to create an object based from the class. This represents the bike that you own earlier in the example, and with this, we created an object from the prototype (class) of the bike. We can now alter the bike object and change its attributes:

  1. class Bike():
  2.    
  3.     __init__(self): # Lay down some initial bike stats
  4.        
  5.         self.color = 'White'
  6.         self.wheels = 2
  7.         self.motor = False
  8. yourbike = Bike() # Create a new Bike object
  9. yourbike.color = 'Flame Red'
  10. yourbike.wheels = 4
  11. yourbike.motor = True

Now, notice that by accessing yourbike, we can change its attributes that were set earlier in the class. However, if we were to create a whole new bike object from the bike class, it would still be a white bike with two wheels and no motor because yourbike is based off of the bike class, but is not a pointer to the class - it's its own object.

Why use classes? Well, it's slightly more comfortable (to me) than using dictionaries, and since you can provide initial variables as well as change variable values later, you can use these to organize things that share attributes. For example, if you have ranged weapons in a game that all have ammo, range, and projectile speed, you might use a class to represent this data.

Well, that's it for this tip. I suppose I should make more of these to further explain how classes work. Anyway, have fun messing around with classes!

12 comments:

  1. How would you call on a class that was created in another scenes script?

    KevinCorrigan

    ReplyDelete
  2. Well, when working in the BGE, you have to store the object created from a class in a variable. So, for example, you would store an object in bge.logic, or store it in a game object and refer to the object for referring to the class object. If you mean that you want to create an object in a script from a class defined in another Python module, import the module, then make a new object from the class in the module, i.e.

    newbike = Vehicles.Bike()

    ReplyDelete
    Replies
    1. __init__(self):

      That Line right there is giving me an invalid syntax error, and if I change it then it doesn't recognize __init__(self)

      Have any Ideas?

      Delete
    2. Nevermind I think I fuigured it out, Thank you for all the help:)

      Delete
  3. you should look more into class inheritance. You could write less setup functions by calling common methods from the parent class instead of rewriting them for every object.

    ReplyDelete
  4. the other nice part about classes over dictionaries is that you can write your own assignment functions for attributes, so for example, when blender tries to update a value, you can overwrite the assignment function for that particular attribute by defining object.__setattr__( ) see here http://docs.python.org/reference/datamodel.html#object.__setattr__

    ReplyDelete
  5. Thanks for the suggestion. Both of those are pretty good reasons to use classes. I'll see about doing a tutorial about class inheritance soon.

    ReplyDelete
  6. This comment has been removed by a blog administrator.

    ReplyDelete
  7. I look forward to knowing how to use this on game objects! i'd like to make my game code more object oriented.

    ReplyDelete
  8. Classes are also good to expand features of objects by making the standard object a superclass and the extra features as subclasses. Helps to divide the classes by common features. If one wishes to ever change a feature in the superclass(es) then the subclasses can override by using the same method name (namespace) because Python returns classes in the order from bottom(sub) to top(super).

    ReplyDelete
  9. Thanks. This maybe is what i'm lacking and the reason im having a hard time creating an in entory. Thanks

    ReplyDelete
  10. There's a typo here Solarlune, def __init__(self):
    Nice blog!

    ReplyDelete