On Sat, 21 May 2011 08:24:34 pm Robert Sjöblom wrote: > I'm trying to wrap my head around classes and their attributes, but > am having a hard time doing so. The websites and books that I have > consulted haven't been much help; most of them assume prior > programming/oop experience, something I lack.
Let's start with a simple question -- what is an object? In programming, an object is a thing that combines data and behaviour together in one handy package. Back in the Dark Ages *wink*, code and behaviour were always separate, so you would have to design a data structure in one place of your program, then write functions to manipulate it somewhere else. If you had two different data structures which needed similar actions, you had to jump through hoops to keep the functions for one separate from the functions of the other. But objects let you keep related pieces of code together, so they don't get in the way of unrelated code with the same name: class Artist: def draw(self): print("I splashed paint on the canvas until it looked like" " my mother on a rocking horse.") class GunSlinger: def draw(self): print("The stranger reached for his gun, but I was too" " quick for him and plugged him full of lead.") The function (actually "method") called draw for Artists doesn't get over-ridden by the method with the same name for GunSlingers: >>> whistler = Artist() >>> wyatt_earp = GunSlinger() >>> whistler.draw() I splashed paint on the canvas until it looked like my mother on a rocking horse. >>> wyatt_earp.draw() The stranger reached for his gun, but I was too quick for him and plugged him full of lead. Here you see object code in action. You start with a class, which is something vaguely like a template. (It's actually nothing like a template, but that will do for now.) Before you can use the class, you normally have to instantiate it. Think of it like this: in the real world, "car" is a kind of machine, or if you prefer, a *class* of machine. But you can't just get into the abstract class of "car" and drive to the shops, you need an actual, concrete, physical car: an *instance* of the class. In object oriented programming ("OOP"), this is normally the same: you create an instance of the class, and then work with that. The instance gets its behaviour (and sometimes its data) from the class. The examples above are classes with behaviour only, no data or state. They never change. That's not very useful. Normally you want to store data in the class instance, sometimes in the class itself. Here's an example: class Paper: colour = "white" size = "A4" This defines a class with no behaviour, only state. In this case, it has two attributes, colour and size. The values stored in the class are global defaults: all Paper instances share the same value. But you can give individual instances their own independent value by assignment: >>> sheet = Paper() >>> sheet.colour 'white' >>> >>> another_sheet = Paper() >>> another_sheet.size = "A5" # cut the paper in half >>> another_sheet.colour = "green" # and paint it >>> another_sheet.colour # check that the change is stored 'green' >>> >>> sheet.colour # and check that the other sheet is unchanged 'white' Normally though, you don't need or want to set default state that applies to all instances. In the above Paper example, it is harmless, but sometimes it can lead to bugs, so be careful with class attributes. So although attributes common to all instances of a class can sometimes be useful, generally people try to avoid them, and it is more common to put off defining the instance's attributes until the instance is created. For that, Python has a special method called "__init__" (that's two underscores at the front and back). When you create an instance by calling Paper(), the __init__ method (if any) is automatically called by Python. class Paper: def __init__(self, colour="white", size="A4"): self.colour = colour self.size = size Now the attributes no longer live inside the class, but inside the instance. Paper instances no longer share global state. Each instance gets its own independent attribute for colour and size, which you can specify when you create it: >>> sheet = Paper("blue", "Foolscap") >>> sheet.colour 'blue' Now, I've skimmed over a couple of important things here. Firstly, syntax: in Python, the syntax for attribute access is with a dot: paper.size lets you retrieve the attribute. To set the attribute, you simply assign to it: paper.size = "A3" Notice that dot is the same syntax used for accessing methods: whistler.draw() That's because in Python, methods are just another attribute, only you can call them with () syntax. This lets you do all sorts of cool and advanced things, like store a method somewhere to use it later: import random if random.random() < 0.5: method = wyatt_earp.draw # no parentheses! else: method = whistler.draw # later... method() # call the method but I digress. The other thing I glossed over was the mysterious "self" parameter in the method definitions. Remember, methods are defined inside the class, not inside the instance. When you call a method, how does the class know which instance it should look at? The answer is, Python does some sleight of hand in the background, changing what you write: whistler.draw() into what actually gets executed: Artist.draw(whistler) That's moderately advanced though, you don't need to care about it, *except* that you have to remember to declare a parameter in all your methods to hold that auto-magic instance argument. Conventionally, we call it "self", but you can call it anything you like. (You can, but you shouldn't.) Forgetting to declare "self" in your methods is one of the more common source of bugs. That's pretty much all you need to know to start using objects. There's a lot more though: inheritance, class methods and static methods (as opposed to ordinary methods), properties, descriptors (advanced!), slots, and more. But one step at a time. Any questions, don't hesitate to ask! -- Steven D'Aprano _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor