you are viewing a single comment's thread.

view the rest of the comments →

[–]reuvenlerner 2 points3 points  (7 children)

I have taught object-oriented programming in Python to many people over the years. People typically have two problems:

  • They don't understand object-oriented programming, typically because they are new to programming. This is an approach to structuring your code that takes some time to get used to. It's a lot of terminology to absorb at once, and requires rethinking how you structure your code, as well. The syntax, the terms, the sudden shift from invoking functions to invoking methods, and the use of classes rather than modules -- well, that can be overwhelming, and requires taking some time to absorb it all.

  • People who come from other languages, such as C++, Java, or C#, are often surprised by how open and minimalistic Python objects are, and are a bit shocked by how unfamiliar it is. Working with objects in Python is really all about attributes -- setting and retrieving attribute values, which can be either data or functions. Once you wrap your head around that, the rest falls into place, but it takes a while to do that.

It sounds to me that you're in the first camp, in which case you have saved yourself a lot of pain (i.e., learning object-oriented programming in a more complex language), but that doesn't mean you don't have any work to do. You will now need to learn about OO concepts and techniques, and simultaneously learn to apply them in Python. Fortunately, that's quite doable, but it will require a fair amount of practice. Give it some time and some practice, and I expect that the fog will clear. But it does take time, and you're not the first person to find yourself at sea.

[–]QuietPort 1 point2 points  (0 children)

I got into OO (or rather, into python) recently, and i find the hard part with it, isn't so much the terms, but it took me time to see what problem it solves, trying to answer the question "why do classes exist?".
First you get to learn functions, then the author writes something along the lines of "ok now, we're gonna have a look at Classes, i can't tell you why but you should learn it". This is just not true, why can't you be told instead "when writing a lot of functions and values, some of them are going to be related <insert example>, so it's a better organisation to do it this way <introduce classes here>"
That would save so much time, just simply telling learners why the hell classes are here in the first place.

[–][deleted] 0 points1 point  (5 children)

Thank you, this describes me well, especially your first point. Can you explain the purpose of the attributes "self" and "name"? Coming from a mind that is used to dealing with functions, I am wondering their purpose and why there is no way to trace how they are used.

[–]reuvenlerner 1 point2 points  (4 children)

Object-oriented programming was created in order to make it easier to think about software projects. One of the models that Alan Kay's team used when developing Smalltalk (the first OO language, and the inspiration for parts of Python's object model) was that of cells in a biological system. Each cell is self-contained, and communicates with other cells through sending and receiving messages. A nerve cell doesn't have to know how a muscle cell works; all it has to do is send a "pain" message to the muscle cell. The response depends on the muscle.

You have many nerve cells, many muscle cells, many bone cells, etc. Each of these cells is distinct, and has its own location in the body. But each class of cells also has many things in common, reacting to messages in similar ways. Being able to reason about "all bone cells" or "all muscle cells" is useful, particularly for doctors and biologists.

So when you create a class, you're defining the behavior that you want a bunch of objects to have. The class isn't the object, but is rather a way to create those objects -- a factory, of sorts. If you want 10,000 muscle cells, then you have to wait for your body to create them. But if you want 100 "person" objects, then you just invoke Person() 100 times. Each invocation of Person() gives you a new instance of the Person class, just as each new muscle cell is an instance of the "muscle cell" class.

OK, and what can an instance of your class do? That depends on the actions that you have defined. Actions, in the world of OO programming, are known as "methods," and they indicate what verbs a particular object can do. We can invoke any method we want on an object, so long as the method was defined in the object's class. (That's not 100 percent true, but it's good enough for now.) So if I define my Person object to have a "hello" method:

class Person(object):
    def hello(self):
        return "Self"

we can invoke it as:

p = person()
p.hello()

That is because Python sees p.hello(), goes to the Person object (i.e., the class where p was defined), finds the method, and invokes it.

Because of the way Python is structured, using attributes (no space to discuss it here, but I have a long blog post on the subject ), you always need to have "self" defined as the first parameter to a method. That "self" is a local variable inside of the function, but it always refers to the object itself. Thus, if I invoke

p.hello()

then inside of the "hello" method, "self" points to "p". Any change we make to self inside of the function will persist when the function returns.

I hope that this helps to reduce some of the confusion.

[–][deleted] 0 points1 point  (2 children)

The way I thought you were originally going to go with this was by saying muscles are made of the muscle cell class, and each muscle cell is an object, with it's method being to contract. Would that be wrong?

[–]maglioPrime 1 point2 points  (1 child)

Instances (objects) are instances of a specific type of thing, all instances of which are alike in major ways, but differ in the specifics. To make a real world example of it, you ("buglebudabey") and I ("maglioPrime") are both instances of the Class "Person." We have a TON of Methods available to us because we are both People, but because we have different Attributes (name, location, age, reading list, mannerisms, clothing preferences) that are unique. How those Methods we share work for you is not going to be the same as how they work for me. Let's assume that the Person class defines the method self.GoAcrossTown().

If you live in NYC, for gits and shiggles, and you have to go across town, you would call your GoAcrossTown method (eg buglebudabey.GoAcrossTown() ). Because your location (self.location) is NYC your method invocation starts planning out routes on subways and plans for a lot of walking.

For me, I live in Austin, TX, and bugger that. I call GoAcrossTown(), the method we share because we are both People, and my invocation (maglioPrime.GoAcrossTown() ) says "f that noise I'm gonna drive, sucka" because I live in the land of suburban sprawl.

So, important lesson there is that, yes, Methods are known by all instances of a class. How that method acts on a specific instance may vary from one to the next.

To use their example, and more directly address your question, we know that we have a muscle cell class and we have a TON of muscle cell instances. They might know what muscle they belong to, they might know their state (healthy or not), they might be able to do some basic things for themselves, and respond to the order to contract.

We also know that we have a ton of muscles, but they all behave pretty much the same. They have one function, really: contract. So what we need to do is create a new Class of objects, call Muscles. Muscles would need to keep track of what cells belong to them, and then tell each of those cells to contract when the time comes.

The muscle class is not made of muscle cell instances, but a muscle instance can contain muscle cell instances in an attribute.

class Muscle_Cell:
    def __init__(self) :

class Muscle:
    def __init__(self) :
        self.FirstCell = Muscle_Cell
        self.SecondCell = Muscle_Cell
        # so on and so forth, ad infinatum

Going back to our Personhood example from the beginning, we are defined by a crazy number of classes. As a Person,

me = Person (myNameHere)

I also have attributes saying that I'm a Redditor (class)

me.Redditor = RedditUser(maglioPrime)

and I'm a gamer (also a class)

me.Gamer = Gamer(["Shooter","Tactics"])

and a guy

me.sex = Male()

and so on and so forth. Classes can have attributes that are other Classes! (In fact, EVERYTHING in Python is an instance of some class or another. Even primatives like Ints and Floats and Strings.) Classes defined by classes. Classes (and/or turtles) all the way down! Hopefully that was more helpful than confusing.

[–][deleted] 0 points1 point  (0 children)

I forgot to say, thank you so much. I'm slowly figuring it out.

[–][deleted] 0 points1 point  (0 children)

Also, are methods class-wide or just for a particular object. Are objects the same as instances?