4

I've been mostly programming in Java and I find Pythons explicit self referencing to class members to be ugly. I really don't like how all the "self."s clutter down my methods, so I find myself wanting to store instance variables in local variables just to get rid of it. For example, I would replace this:

def insert(self, data, priority):
    self.list.append(self.Node(data, priority))
    index = len(self)-1
    while self.list[index].priority < self.list[int(index/2)].priority:
        self.list[index], self.list[int(index/2)] = self.list[int(index/2)], self.list[index]
        index = int(index/2)

with this:

def insert(self, data, priority):
    l = self.list
    l.append(self.Node(data, priority))
    index = len(self)-1
    while l[index].priority < l[int(index/2)].priority:
        l[index], l[int(index/2)] = l[int(index/2)], l[index]
        index = int(index/2)

Normally I would name the local variable the same as the instance variable, but "list" is reserved so I went with "l". My question is: is this considered bad practice in the Python community?

Just some guy
  • 1,909
  • 4
  • 21
  • 32
  • 3
    It's potentially bug-forming: if you reassign the variable instead of modifying it, it won't refer to `self` anymore. – Mark Ransom Nov 05 '15 at 17:44
  • 1
    It's confusing to other Python programmers, which is definitely not good. It's also not very Pythonic: `self` provides explicit scoping, which is encouraged as per Python's "explicit is better than implicit" philosophy. – Kyle Strand Nov 05 '15 at 17:49
  • 1
    In Python, underscore is used to avoid clashes with keywords and builtins: list_ = self.list. Personally, I am using local variables for brevity only if I they are "read-only" inside a method. Interesting, that I am lacking "self" a lot in Java: explicit is better than implicit, you know. – Roman Susi Nov 05 '15 at 17:49
  • 1
    Actually, if you grep Plone modules, you will find a lot of "context = self.context". And even more of "x = self.x" – Roman Susi Nov 05 '15 at 17:55
  • 1
    Also as a side comment: int(index/2) is shorter to write like index//2 - especially in Python 3 – Roman Susi Nov 05 '15 at 18:20

2 Answers2

2

Easier answer first. In Python, underscore is used to avoid clashes with keywords and builtins:

list_ = self.list

This will be understood by Python programmers as the right way.

As for making local variables for properties, it depends. Grepping codebase of Plone (and even standard library) shows, that x = self.x is used, especially,

context = self.context

As pointed out in comments, it's potentially error-prone, because binding another value to local variable will not affect the property.

On the other hand, if some attribute is read-only in the method, it makes code much more readable. So, it's ok if variable use is local enough, say, like let-clauses in functional programming languages.

Sometimes properties are actually functions, so self.property will be calculated each time. (It's another question how "pythonic" is doing extensive calculations for property getters) (thanks Python @property versus getters and setters for a ready example):

class MyClass(object):
    ...        
    @property
    def my_attr(self):
        ...

    @my_attr.setter
    def my_attr(self, value):
        ...

In summary, use sparingly, with care, do not make it a rule.

Community
  • 1
  • 1
Roman Susi
  • 4,135
  • 2
  • 32
  • 47
1

I agree that explicitly adding "self" (or "this" for other languages) isn't very appealing for the eye. But as people said, python follows the philosophy "explicit is better than implicit". Therefore it really wants you to express the scope of the variable you want to access.

Java won't let you use variables you didn't declare, so there are no chances for confusion. But in python if the "self" was optional, for the assignment a = 5 it would not be clear whether to create a member or local variable. So the explicit self is required at some places. Accessing would work the same though. Note that also Java requires an explicit this for name clashes.

I just counted the selfs in some spaghetti code of mine. For 1000 lines of code there's more than 500 appearances of self. Now the code indeed isn't that readable, but the problem isn't the repeated use of self. For your code example above: the 2nd version has a shorter line length, which makes it easier and/or faster to comprehend. I would say your example is an acceptable case.

Felk
  • 7,720
  • 2
  • 35
  • 65