On Tue, Oct 22, 2013 at 04:25:59PM +0200, Sven Hennig wrote: > Hello, I would like to learn a programming language and have decided to use > Python. I have some programming experience and doing well in Python. What > really causes me problems is OOP. > I'm just dont get it... I'm missing a really Practical example. In every > book I've read are the examples of such Class Dog and the function is bark. > Has > anyone an OOP example for me as it is really used in real code, so I can > better understand the concept? I do not know why this is so hard for me.
I can sympathise. You wouldn't believe how long it took me to really grok object-oriented programming. I just didn't get it, until I started thinking of OOP as being just syntax for keeping functions (called "methods") close to the data they belong with. There is more to OOP than that, but that was my first step: OOP helps you keep your functions close to the data they work with. In conventional procedural languages, if you had a function that operates on a string, you would write something like this: Struct string = ... # define a string here # later in the file, perhaps many pages later: function upper(some_string): result = make a new string for char in some_string: if char = 'a': add 'A' to result if char = 'b': add 'B' to result ... if char = 'z': add 'Z' to result else add char to result return result (Aside: don't program uppercase like that! There are more efficient ways, and in Python, it is already provided!) So the problem with this is that your data (say, strings) and the functions that operate on your data (say, upper, lower, and many others) can end up being defined far away from each other, which makes editing the code painful. With OOP, the first change is that the syntax is changed to bring the functions (called "methods") together with their data: class string: # put code here to define the "string" data class # now define all the functions that work on strings def upper(self): # code for "upper" goes here def lower(self): # code for "lower" goes here # any other string methods go here Then, later, instead of writing: mystring = "blah blah blah" print upper(mystring) # this doesn't work since upper is a method we have a slightly different syntax: print mystring.upper() # use this instead That's all you need to know to start using object oriented programming in Python! Many operations are implemented as methods, for instance strings have upper and lower methods, lists have append and remove methods, and many more. You'll soon learn the operations like len() that aren't methods, but old-school functions. As I said, there is a lot more to OOP than just making it easier to organise your program files, but that was the realisation that helped me get OOP. The next step is to understand "inheritance". Inheritance means that you can create a new class (the subclass) which inherits -- borrows -- data and methods from another class (the super class). Here is a stupid example: class StupidStr(str): # inherit from str def upper(self): return "***" This class StupidStr is exactly like the ordinary string, except the upper() method has been replaced to do something trivial and stupid: py> s = StupidStr("Hello World") py> s.lower() # inherits the behaviour of normal str 'hello world' py> s.upper() # overrides the normal upper method for my stupid one '***' Why would you do this? Well, obviously you wouldn't do something so stupid except as an exercise. It's hard to give *simple* real life examples that aren't contrived, but here's one that works for me: Suppose you're writing software to control a model car. You might start off by collecting some basic defaults: class DefaultModelCar: model = "Unknown" BRAKE_COMMAND = "B" FORWARD_COMMAND = "F" REVERSE_COMMAND = "R" ACCELERATE_COMMAND = "A" TURN_LEFT_COMMAND = "TL" TURN_RIGHT_COMMAND = "TR" def send_command(self, command): # Send a command to the model car. # Put the code here to actually communicate with the car. ... def forward(self): # Drive forward. if self.direction == "Reverse": # Brake first, then move forward. self.stop() self.send_command(self.FORWARD_COMMAND) self.send_command(self.ACCELERATE_COMMAND) self.direction = "Forward" def reverse(self): if self.direction == "Forward": self.stop() self.send_command(self.REVERSE_COMMAND) self.send_command(self.ACCELERATE_COMMAND) self.direction = "Reverse" def stop(self): self.send_command(self.BRAKE_COMMAND) self.direction = "Stopped" and so on. Now, this default set of commands probably won't work for any actual model car, but at least you can run it and test that it works as you expect: car = DefaultModelCar() # Create a car instance car.forward() if car.direction == "Forward": print("Okay, car is moving forward") else: print("There's a problem...") car.stop() Now you want to control a couple of specific models: class SpeedyCar(DefaultModelCar): model = "Speedy Car Model X" BRAKE_COMMAND = "10" FORWARD_COMMAND = "11" REVERSE_COMMAND = "12" ACCELERATE_COMMAND = "34" TURN_LEFT_COMMAND = "41" TURN_RIGHT_COMMAND = "42" class MegaCar13(DefaultModelCar): model = "Mega Car Model M13" BRAKE_COMMAND = "%9" FORWARD_COMMAND = "%1" REVERSE_COMMAND = "%2" ACCELERATE_COMMAND = "%6" TURN_LEFT_COMMAND = "%7" TURN_RIGHT_COMMAND = "%8" And that's it! If you've done your programming right, most of the hard work has been done in the default class, and all you need to do is change a few settings, and it should just work. (In reality, each model car will probably have it's own special way of receiving commands. But let's just pretend that all model cars accept commands the same way, only the commands themselves are different.) Sometimes you'll find that you need to override a method with one a little different: class MegaCar14(MegaCar13): model = "Mega Car Model M14" # Brakes are crap on the M14. def stop(self): for i in range(5): self.send_command(self.BRAKE_COMMAND) self.direction = "Stopped" But everything else works just as before. Now you can have a race: a = SpeedyCar() b = MegaCar13 c = MegaCar14 cars = [a, b, c] # Start the cars, let them drive for 10 seconds, and see which gets # further. for car in cars: car.forward() time.sleep(10) for car in cars: car.stop() Notice that even though each model car needs different commands to control it, all those details are hidden away inside the class. From the outside, you use exactly the same commands to control it: forward, stop, reverse, etc. -- Steven _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor