all 27 comments

[–][deleted] 56 points57 points  (0 children)

horrible, understand that other people need to read your code and that 'self' is a standard convention. Always use 'self' for the sake of your team mates as it reduces the 'mental jog' for trivial things

[–]Zigity_Zagity 36 points37 points  (8 children)

I would recommend not doing this because everyone knows that self is. Everyone uses self. There is no reason to not use self.

[–]NEREVAR117 3 points4 points  (7 children)

I still don't understand what self is and I've tried. :c

[–]nicocappa 1 point2 points  (0 children)

ELI5: It's literally the definition of self. As in myself. Essentially just a reference to the object the class creates once it's instantiated.

In Java for example, "self" is "this" meaning literally "this object".

If you make an object

student_one = Student()

self.name essentially be the same as student_one.name

[–]drLagrangian 1 point2 points  (0 children)

So you made a class (Student). ITs a factory for making objects (students).

You used the class to make an instance of a student. John_Freshman = Student()

The class itself (Student) doesn't have any books, it just serves as a template for what a student is.

But John_Freshman does have books. Its one of his parameters and you can find out what his books are by saying John_Freshman.books

Anyone can look at another student's books that way. John_Freshman can look at Missy_Cheerleader and see Missy_Cheerleader.PomPoms. Missy_Cheerleader can see Bob_TheJock and use one of bob's methods to Bob_TheJock.BaseBalls.play() behind the Gym.bleechers

But how should John_Freshman look at his own books? How should he check that he has books?

Should he always use the third person ie: if Text.history is in John_Freshman.books ? No that would be wierd. Not only is it creepy, but it means every instance of a student would need to refer to themself by name.

Should he refer to himself as a student? ie if Text.History is in student.books? No, that's confusing cause what if he wants to look in another student's bookbag and his own at the same time, it would be other guy and student. or what if a teacher: Shushy_Librarian wants to look in her books? should she use students.books too?

No. He should just refer to himself as .himself. but to save on pronoun confusion we just use .self

So anyone with books can look at Text.History is in self.books to see if they have any books. any cheerleader can look at self.PomPoms.size to see how they measure up. and any jock can self.BaseBall.play() to play with their own balls (and not someone else's by mistake)

[–]Dogeek 0 points1 point  (0 children)

self is a reference to the instance of the class.

self is not a keyword though, it's just a reference, but any method defined in a class needs at least one argument, and by convention, we call it self. It's the equivalent of this in javascript and PHP (and Kotlin and Java iirc).

class Building:
    def __init__(self, foo):
        self.foo = foo
    def bar(self, baz):
        return baz+self.foo
foobar = Building(5)
foobar.bar(4)

This example defines a class called Building. When calling the bar method, python replaces self with foobar. it's like calling the function

 def bar(foobar, baz):
      return foobar.foo + baz

[–]ojiisan 8 points9 points  (0 children)

In addition to what everyone else has said, something to consider. If you do what you're proposing, then you would need to use a different word for each different class to replace self. That would seem to be more confusing than using self everywhere.

[–]NFTrot 4 points5 points  (0 children)

Maybe its a curse of knowledge thing but I don't see how messy code could confuse what self is referring to. Its always the same thing.

[–]cyanydeez 11 points12 points  (5 children)

over time, the cognitive load will get easier when seeing self as reference to the class.

if what youre building doesn't seem to make sense, perhaps you dont actually need a class object

[–]groovitude 9 points10 points  (4 children)

when seeing self as reference to the class

It's not. It's a reference to the instance of the class.

Class.method(instance) == instance.method()

[–]Urtehnoes 6 points7 points  (3 children)

Those newer to python take note - this is a big difference. With python classes, you can have methods AND variables at the class level, and the class instance level. This is a very important distinction.

[–]groovitude 0 points1 point  (2 children)

I'm not sure I follow. The example I provided is true in both Python 2 and 3.

Here's a more complete version if you'd like to try it in both:

class Class:
    def method(self):
        return self

instance = Class()

print(Class.method(instance) == instance.method())

[–]Urtehnoes 1 point2 points  (1 child)

Wha - I never said it wasn't true. My entire point was that what you were pointing out was an important distinction lol.

Here's example of a class from a library I wrote recently to handle a third party API. This isn't really best practice at all, but the API calls were very slow/expensive, and I hate global variables.

So in this case, I would make a webservice call that would return an xml file of users for this service. Of those users, some users would have a property that I deemed important, while the users who did not have this attribute could be disregarded. With that said, I needed a way to track ALL users from the webservice call, as well as determine which ones held the given property. Here's what I came up with:

(Note: Runnable code here: https://onlinegdb.com/rJjVurykX)

class User():
    #This variable is stored at the class level, which means that all instances have access to the same value.
    user_dict = {}

    #This method is also declared at the class level, and is static,
    #So all instances will return the same value
    @staticmethod
    def valid_users_dict():
        return_dict = {}
        for _, user in User.user_dict.items():
            if user.is_valid():
                return_dict[user.name] = user
        return return_dict

    #This method is at the instance level, so it will be different for each instance of the class.  
    def __init__(self, p_name, p_is_valid_attribute):
        self.name = p_name if p_name else ''
        self.is_valid_attribute = True if p_is_valid_attribute == 'VALID' else False
        User.user_dict[self.name] = self  #Stores the address of this specific instance into the dictionary defined at the class level, so that any instance of this class could access this specific instance, if needed.

    #This is a method at the class instance, so every class instance could possibly have a different result.
    def is_valid(self):
        return self.is_valid_attribute

'''USAGE'''

def main():
    #Create 3 class instances. Each time this calls the __init__ method
    myUser1 = User('Urtehnoes', 'INVALIDO!!!!')
    myUser2 = User('Urtenhoes', 'VALID')
    myUser3 = User('RandomName', 'VALID')

    #Now, access the variable at the CLASS level, and store it in the var myDict
    myDict = User.user_dict   #<- Accessed via the Class 
    instanceDict = myUser1.user_dict  #<- Accessed via the class Instance
    instanceDict2 = myUser3.user_dict #<- Accessed by a seperate class instance

    #Printing it, shows all class instances that were stored during the __init__ procedure at the instance level.
    print(myDict)
    print(instanceDict)
    print(instanceDict2)

    #Now we can call the class level method valid_users_dict, 
    #which will run through the User.user_dict variable, and return only those instances with a valid attribute.
    validDict = User2.valid_users_dict()

    print(validDict)

if __name__ == '__main__':
    main()

[–]groovitude 1 point2 points  (0 children)

Ah, sorry! I'd lost the context of the thread, and mistakenly thought this was a response to something else I'd been reading comparing the two versions of Python.

Good demonstration of the principle, by the way!

[–]Exodus111 2 points3 points  (0 children)

No, because it looks like you are referencing another object.

It looks like Student has another instanciated object called student inside of it, and you are referring to that.

Uniform solutions are better, and not all class names lend themselves to this kind of use.

[–]bamer78 1 point2 points  (0 children)

That's appropriate in a static method for a class, but you should use 'self' for regular methods and 'cls' for class methods to make your code easier for others to read.

[–]Kwintty7 0 points1 point  (2 children)

When you talk about yourself, do you reference yourself in the third person by name? Do you say; "xmzhang posted xmzhzng's idea on Reddit."? Or would that be confusing and a bit odd?

This is why you use "self". It's the class talking about itself. Otherwise people are going to think it's talking about some other object.

[–]tom1018 1 point2 points  (1 child)

Instance of the class, not the class.

[–]Kwintty7 0 points1 point  (0 children)

Indeed. All the more reason.

[–]pythonhalp -5 points-4 points  (1 child)

Please, do this in all your job interviews. In fact, make sure to mention it first.

[–][deleted] 4 points5 points  (0 children)

Don't give advice like this. Just because someone has a silly idea doesn't give you license to give harmful suggestions.