Python classes
|
[edit] Tutorial: Python classesRequires: ES 2.x [edit] Tutorial Overview[edit] Table of Contents
[edit] DescriptionA short overview of creating classes in Python. Looking at class creation, scope and instancing classes. The tutorial comes in 2 parts, the first deals with basic classes and how to make them. The second discusses more advanced uses and discusses in more depth why classes in Python are so useful and powerful. [edit] Tutorial Content[edit] Part 1: Basic Classes[edit] Why use classes?Functions are great aren't they? Lets you do the same generic stuff over and over again with minimal lines of code (functions by the way are also called methods in Python and are created by the def <name>(<args>): syntax). There is however a big drawback to functions - it's called variable scope. When you run a function in a script all the variables created or used in it are generally private to that function. Unless you specifically mark them as global you cannot use them outside of it. So what if another function uses the same variable in a different way (further processing for example). You would have to make the variable global or pass it from one function to the next. This could cause further problems if you use the same variable somewhere else in a different way. Pretty much this problem can be summed up with the phrase "functions do not store data - each time they run they start over" Ok I cant put it any simpler than this excerpt I found on another help site: Functions don't store any information like variables do - every time a function is run, it starts afresh. However, certain functions and variables are related to each other very closely, and need to interact with each other a lot. For example, imagine you have a golf club. It has information about it (i.e. variables) like the length of the shaft, the material of the grip, and the material of the head. It also has functions associated with it, like the function of swinging your golf club, or the function of breaking it in pure frustration. For those functions, you need to know the variables of the shaft length, head material, etc. Chances are that you also have more than one golf club. Without classes, you need to write a whole heap of code for each different golf club. This is a pain, seeing that all clubs share common features, it is just that some have changed properties - like what the shaft is made of, and it's weight. The ideal situation would be to have a design of your basic golf club. Each time you create a new club, simply specify its attributes - the length of its shaft, its weight, etc. Basically, then, what a class does is group lots of functions and variables that are used closely together. It allows you to create 'instances' of the class as many times as you like - all of the data (variables) are stored separately in an instance so you can modify each one however you like and it will not affect other instances of the class. Instances? Instances are easy - simply put an instance of a class is just you telling python you want to start using the class. It will create all the variables associated with it and do anything else YOU coded to happen when the class initializes. Usually you store a class instance to a variable. Then you are able to reference functions or variables in the instances (eg: <instance variable>.<class function or var>...). [edit] Initializing classesYou create a class by using the line: class <class name>(<type>): Anything indented after that line will be included in the class (until of course you put something on the same tab level as the class). For now do not worry about the <type> attribute - this defines the classes inheritance and will be discussed shortly. For now we will just use the 'object' type. For example: # Demonstrating class creation and what is 'in' the class and what 'isn't' class my_class(object): avar = 'a class variable' def __init__(self): #this tab level is inside the __init__ function of the classs pass def newfunc(self): # this is a new function in the class pass def notinclass() # This function is NOT included in the class pass [edit] About selfself is the first parameter of every method inside a class. Variables and Methods inside a class are stored locally in every instance of it called, Self is the way a method can talk to other members of the class (methods & variables). Unfortunately Python will not make this automatically available inside class methods - instead it is (silently) passed as the first argument in ANY class method. Silently passed simply means that Python will pass it automatically so you do not need to pass it manually. Although the first parameter of every method inside a class doesn't HAVE to be called self, it is Python tradition to do so. In comparison with PHP, self. = $this-> For example: # Demonstrating self class Example(object): MyVar = 1 # This variable will set as self.MyVar def __init__(self): # As you can see, self is the first parameter print self.MyVar self.conventionalWay() # Don't need to pass self, Python does this for us. self.unconventionalWay() def conventionalWay(self): # This method can be referenced anywhere inside this method by using self.conventionalWay() # This method can call the local variable / method set by using self.<identifier> print self.MyVar def unconventionalWay(dontcallmeself): # This method can still be referenced anywhere inside this method by using self.unconventionalWay() # This method can call the local variable / method set by using dontcallmeself.<identifier> # It is simply convention to use self print dontcallmeself.MyVar Example() Output:
1 1 1
It is recommended you use the self naming convention in your scripts, however, to allow other coders to understand what you are doing. [edit] Magic methodsNo, its not something from Disneyland, its a really cool addition to the new Python class style. They are called on certain events, take a look at the list of some of them below:
class TestClass(object): def __init__(self): print 'object = TestClass() ran' def __getitem__(self,name): print 'var = TestClass[%s] ran' % name return 0 def __setitem__(self,name,value): print 'TestClass[%s] = %s ran' % (name, value) def __call__(self,printwhat): print 'TestClass(%s) ran' % printwhat print printwhat object = TestClass() var = object['whatever'] object['woohoo'] = 0 object('Hello, World!') Output: object = TestClass() ran
var = TestClass['whatever'] ran
TestClass['woohoo'] = 0 ran
TestClass('Hello, World!') ran
Hello, World!
[edit] Calling / Initializing instancesAs you can see in the examples above, I have initialized, and called classes. Simply, all you are doing it telling Python to create a version of <class> in <var> you specified. # Demonstrating calling class call_me_one(object): def __init__(self,desc): self.myvar = desc class call_me_two(object): myvar="Class 2 - but it doesnt change" def __init__(self): pass classone = call_me_one('First class one') # calls our first class passing it something for desc classoneagain = call_me_one('Another class one') # Calls our first class in another instance classtwo = call_me_two() # Note we pass nothing here as __init__ takes no arguments classtwoagain = call_me_two() print classone.myvar print classoneagain.myvar print classtwo.myvar print classtwoagain.myvar The output would be: First class one Another class one Class 2 - but it doesnt change Class 2 - but it doesnt change You can also put classes into items in dictionaries and lists! This works the same as calling them to variables. classes = {} # create dictionary classes['myclassone'] = call_me_one('Class one in a dictionary!') print classes['myclassone'].myvar Add it to the first example and it would print: Class one in a dictionary! [edit] Part 2: Advanced ClassesNone of this is harder than part 1 but has the potential to confuse you if you dont follow closely You may remember at the start I told you to ignore the type attribute in a class call (class <name>(<type>):), and that for the time being 'object' would be used in the examples. Now the time has come to look more in depth at what the type attribute is for and how OOP comes into the equation. By this point you should have a fairly good understanding (provided you have followed this tutorial so far) of what classes are and what they can do. Let's just define it again now: Classes provide a way to group together methods and variables that tend to interact together, or rely on each other, into an easy package that can be instanced multiple times If that makes total sense to you then you are ready to continue, if not try reading it all again. The reason I am being so careful with this is that the concept of Object Oriented Programming and types is what tends to end up confusing people. Even the most experienced programmers who already know classes inside out run and hide when OOP is mentioned, really they shouldn't; it is a very simple concept that just gets lost because of it's similarity to classes. [edit] What is OOP?OOP is Object Oriented Programming. What that rather ambiguous title actually means in terms of Python programming is classes under a new name. Or rather class instances under a new name. Time for a metaphor! Imagine you have a class called Dog, this provides methods to define the dog (eg: bark() for when it barks, walk() for when it walks, piddle() for when it... you get the idea). It also provides variables that defines the dogs properties; such as it's height, it's colour, it's coat, it's tail wag speed and so on. However the class is static - it doesn't describe a dog, it just outlines how a specific dog will be described. Then we have the object Brutus, Brutus is out loving (and slightly dangerous) dog. It is an instance of the class Dog - however now we have described it's characteristics / properties (variables) and are able to let it bark, walk, widdle etc methods. Hopefully that rather wacky example makes it simple to understand. Objects are simply specific instances of classes. There is nothing revolutionary about this - in effect it is just a fancy name for what5 we were already doing anyway. However this is not the end of OOP, as we are about to see. It's time to discuss inheritance. [edit] The Type attribute & inheritanceInheritance is one of the most powerful aspects of OOP. It allows your classes to inherit traits, methods and variables from other 'parent' classes. When you specify parents to a class Python first creates the parents and then modifies it with your class methods / variables. You can overwrite any of the methods defined in a classes parents (and if you do so you will have to uniquely call the parents method within the new one if you wish to use it). To start making use of inheritance you need to use the type attribute, previously we were using 'object' as our type; 'object' is called a base class. It is simply a prototype class with no working methods. When you create a class your inheriting basically nothing, just setting it up as an object, which isn't very interesting. class myclass(object): def __init__(self): print "Booooring" However you can set any class as a parent - even ones you've written yourself. The easiest way to describe how inheritance works precisely is with a demonstration. class baseClass(object): ''' This is our base class ''' def __init__(self): print "(BaseClass) Foo!" def baseClassMethod(self): print "This method was created in the base class" class baseClass2(object): ''' This is another base class - you can inherit from more than one class! Note it has no init method. ''' def baseClassMethod2(self): print "This method was created in the second base class" class childClass(baseClass, baseClass2): ''' This is the child class - it inherits all the methods from the 2 base classes we wrote above ''' def __init__(self): ''' The __init__ method OVERWRITES the __init__ method in the base class. ''' print "This is the child class" # Using super() we can call methods in the parents of a class that are overwritten super(childClass, self).__init() def baseClassMethod2(self): ''' This method overwrites the one in baseClass2 Because we dont call the parent class method (using super()) it is just 'destroyed' from this class ''' print "This method was recreated in the child class" # Demo code class_demo = childClass() # Call baseClassMethod - as created in the first baseclass class_demo.baseClassMethod() # Call baseClassMethod2 - as created in the 2nd class BUT recreated in the child class_demo.baseClassMethod2() Output: This is the child class (BaseClass) Foo! This method was created in the base class This method was recreated in the child class [edit] ConclusionHopefully you will now have some idea of the power of classes and how you could use them. In all probability they will not have a use for simple scripts but for larger ones it provides an easy and clean structure to build with. It is probably recommended to use classes where possible in scripts. [edit] Thanks for reading |
|
