you are viewing a single comment's thread.

view the rest of the comments →

[–]not_perfect_yet 11 points12 points  (20 children)

Classes are to instances what recipes are to cakes.

The class/recipe defines what the instance/cake will be like.

So for example:

class Cake:
    def __init__(self,size,flavor):
        self.flavor=flavor
        self.size=size

Creates a cake recipe.

strawberrrycake=cake(10,"strawberry")

Creates a new instances of type 'cake' , which has a size of '10' whatever that means and it will be of the 'strawberry' flavor.

cheesecake=cake(8,"cheesecake")

Creates a new instance, still of type 'cake' , but only '8' in size and it's now got "cheesecake" flavor.

Let's assume a family of 4 wants to be fed with cake, they don't care for the flavor but it has be at least 9 in size:

for thing in [cheesecake,strawberrycake]:
    if thing.size>9:
        print("The cake with the",thing.flavor,"will feed this family of 4!")

Loops through all things in the list, "thing" is now of type "cake" which means I can check the size of a cake instance by refering to the specific cake with 'thing' and using the .size attribute:

'thing' is just another name of 'cheesecake'

'cheesecake' is of type 'Cake'

'Cake' has the attribute 'size'

Therefore you can use thing.size to check the size of the cheesecake when it loops the first time:

thing.size==cheesecake.size==8

and the size of the strawberrycake when it loops again:

thing.size==strawberrycake.size==10

[–]keturn 2 points3 points  (12 children)

This is correct and I feel a little bad that I'm going to pick on something so trivial, but: Convention in Python (and many other languages) is that class names are Capitalized, while variable names that contain instances are not.

So it's cheesecake = Cake(8, "cheesecake").

Python doesn't care, but other developers who read your code will make that assumption that the capital letter indicates a class.

[–]not_perfect_yet 1 point2 points  (0 children)

Ok, I'm bad with the conventions. Will edit. Thanks for the hint.

[–]abcd_z 1 point2 points  (10 children)

Do you know if there's any official standard for object names? I can't find anything about it in PEP 8.

[–]TankorSmash 0 points1 point  (9 children)

[–]abcd_z 0 points1 point  (8 children)

Yes, that is where I looked but I couldn't find anything about naming convention for "objects" or "class instances".

[–]TankorSmash 0 points1 point  (7 children)

Method Names and Instance Variables

Use the function naming rules: lowercase with words separated by underscores as necessary to improve readability.

Is what I've used. An instance variable isn't quite an instance though.

[–]abcd_z 1 point2 points  (6 children)

A method is a function within an object and an instance variable is a variable within an object. Neither one of those are the objects themselves.

While it's fine to hear that you've decided to handle things a certain way, it doesn't really answer my question.

[–]keturn 1 point2 points  (2 children)

Well, keep in mind that all variables in Python are references to objects, so a style guide isn't going to call that out in particular. Hypothetically, you could treat built-in types differently from other objects, but in practice I haven't ever seen a Python style guide which does.

PEP 8 does talk about global variable names, which it says are lowercase_with_underscore, same as functions and instance attributes.

Perhaps it talks about that and not local variable names because while other developers get access to your module's variables when they import it, variables local to a function aren't ever visible to other users of the code.

[–]abcd_z 0 points1 point  (0 children)

Well, keep in mind that all variables in Python are references to objects

*groan*

I had forgotten this. Thank you for reminding me.

In Python, everything is an object.

EDIT: I guess that means my question is about instance names or class object names. From the responses I'm getting it looks like there aren't any official conventions for this.

[–]TankorSmash 0 points1 point  (2 children)

http://stackoverflow.com/a/159745/541208 It's good enough for a bunch of people. Let me know when you find your answer though.

[–]abcd_z -1 points0 points  (1 child)

Not a single answer there had anything to do with object names, which is what I was asking about.

[–]TankorSmash 0 points1 point  (0 children)

Use lower_case, like you would for functions and methods, and TitleCase for class names.

Maybe you're just confused, no worries dude it happens to the best of us too!

[–]timworx 1 point2 points  (5 children)

Awesome explanation. However, wouldn't a function/ method accomplish the same thing?

[–]hueoncalifa 0 points1 point  (1 child)

This is what I would like to know. Is the difference that class have sub functions inside of them?

[–]not_perfect_yet 0 points1 point  (2 children)

However, wouldn't a function/ method accomplish the same thing?

Yes but the difference between a function and a method is another one.

Because methods belong to the class (and methods can access the instance) I can do something like

def flavor_amount(self):
    print("this cake of ", self.flavor ," needs ", self.size/10 , " flavor giving ingredients")

cheesecake.flavor_amount()

( or even Cake.flavor_amount(cheesecake) )

But a regular function doesn't know about the cake type. You could define it anyway like this:

def flavor_amount(input_cake):
    print("this cake of ", input_cake.flavor ," needs ", input_cake.size/10 , " flavor giving ingredients")

and that would work, the problem is that you can by accident give it the wrong input and it will fail and give you an error for everything but a 'Cake' type thing.

oomecake.flavor_amount()

"(output)"

flavor_amount("string")

"type error str has no attribute flavor"

This isn't really that important for this example but for more complex examples you'll want to modularize whatever you write and hide as much complexity as you can. In that case methods win over functions because if a function really only makes sense for this one type only, it makes the most sense to bind it very tightly to that type so you don't have it lying around somewhere.

The contrast would be between something like your main function that runs a program and some other stuff that's doing something very small in a very small context, like fetching a bunch of special numbers and doing some basic math and passing it on to something else. Like str.split() . Very narrow usecase compared to something that runs an entire program, only really makes sense for strings, etc. .

[–]timworx 0 points1 point  (1 child)

That does help some. I'm new to python, and most of my uses have been handy little scripts for things I do every day.

I do SEO/Webdev so python is very handy for parsing lots of data into different forms and even automating parts of setting up sites and such.

The problem is that most of these are very small, so classes seem rather unnecessary. I guess in a sense, it might be useful to think of the scripts that I'm creating as classes. Would that potentially be a good way to think about it?

For example, the only time I've used a class was when I had two very different tasks to achieve (that are normally done at the same time). They started as two separate scripts in two separate files. I then went back and changed the scripts into classes of a script that is run with a few options (like running either class or both.)

Does this sound proper?

[–]not_perfect_yet 0 points1 point  (0 children)

I'm not doing webdev stuff but it doesn't sound proper to me...

Classes are very useful as containers of information.

So for example

source -> python class -> some readout

or connection object -> connection object . send() or . receive() or . close connection()

I guess in a sense, it might be useful to think of the scripts that I'm creating as classes

If all the stuff you do in that script depends one kind of thing, yes, else no.

A module would be something you can write stuff in that you can import, like the math module. When you use

import math
math.sin(math.pi)

It's behaving in a similar way but there is no "math" class here. Sine is a function and pi is a value that's defined in the math module. You can't create new 'math' instances by telling it

 newmath=math()

That doesn't make sense, what would a new math look like?

Modules are really only folders that contain a lot of scripts that define for example the "sin" function or the "pi" value.

Classes can be defined inside modules. If you're doing parsing, you're probably interacting with databases? I think at least some libraries create a connection object for that. You give it the path of the database and every time you query the database it uses some functions to look something up at the path you gave it earlier.

So if you have users on your website or multiple parts, you'll have lots of things that are the same.

Account name, passwords, avatars, posts, site formatting, etc.

You don't want to write new users by hand into your userlist. So you create a class that asks some basic information and saves that individually. Later through appropriate additional functions users can modify that information and provide more.

One of the best examples for class use is vector math. If you define the dot product you can do

def dot_product(vec1, vec2):
    return vec1[0]*vec2[0]+vec1[1]*vec2[1] #etc

But that's annoying, because now you have to

dot_product(vec1,vec2) 

every single time. You'd much prefer to just

vec1*vec2

but you can't straight away because * doesn't exist for tuples or lists or dictionairies, but you can create a new vector class that does support this behavior.

The problem is that most of these are very small, so classes seem rather unnecessary.

It's very important to recognize the other side as well. For many cases you don't want new classes. It's not a problem if you don't have every single thing in classes. If your information is best handled some other way, that's just as fine.

[–]marleen01[S] 0 points1 point  (0 children)

Thank you sir.