[Python-ideas] Mitigating 'self.' Method Pollution

Nikolaus Rath Nikolaus at rath.org
Sun Jul 12 20:28:04 CEST 2015

On Jul 11 2015, David Mertz <mertz-vlcHsuTvavqeZLLa646FqQ at public.gmane.org> wrote:
> On Sat, Jul 11, 2015 at 12:10 PM, Nikolaus Rath <Nikolaus-BTH8mxji4b0 at public.gmane.org> wrote:
>> > class Vector:
>> >     def abs(self):
>> >         return sqrt(x**2 + y**2 + z**2)
>> >         # versus
>> >         return sqrt(self.x**2 + self.y**2 + self.z**2)
>> >
>> >
>> > I expect that most people, with any
>> > knowledge of vectors, would have understood that the x, y, z in the
>> > first return must refer to coordinates of the vector.
> This is a great example of why the proposal is a bad one.  Yes, not using
> magic makes a one-line function slightly longer (and even slightly less
> readable).
> But I also don't want to have to guess about WHICH 'x' or 'y' or 'z' is the
> one being used in calculation of Cartesian distance.  Sure, an obvious
> implementation of a Vector class probably has x, y, z attributes of self.
> The example was rigged to make that seem obvious.  But even then, I don't
> really know.  Maybe the z direction of the vector is stored as a class
> attribute.  

So how do you know if z is a class or an instance attribute if you write
"self.z" instead of "z"?

> Maybe the class expects to find a global definition of the z direction.

With the proposal, the above would actually read

     def abs(self):
         self x, y, z
         return sqrt(x**2 + y**2 + z**2)

so it is obvious that z is not a global but an attribute of self.

> No one stops you now from giving local names to values stored in the
> instance within a method body.  But when you do so, you KNOW 30 lines later
> that they are local names, even after the "local-looking name is actually
> an attribute" declaration has scrolled away.

As Steven has so nicely written in the mail that I responded to:

| If you are writing "enterprisey" heavily object oriented code, chances 
| are you are dealing with lots of state, lots of methods, lots of 
| classes, and you'll need all the help you can get to keep track of where 
| that state lives. You will probably want explicit self for every 
| attribute access, or a pseudo-self naming convention like m_ in C++, to 
| help keep it straight in your head. *Understanding the code* is harder 
| than writing it in the first place, so having to write a few extra 
| selfs is a negligible cost with a big benefit. Attributes are special 
| because they are state, and you have lots of state.
| But look at Michael's example code. That's real code too, it's just not 
| enterprisey, and there are many Python programmers who don't write 
| enterprisey code. They're beginners, or sys admins hacking together a 
| short script, or editing one that already exists. For them, or at least 
| for some of them, they have only a few classes with a little bit of 
| state. Their methods tend to be short. Although they don't have much 
| state, they refer to it over and over again.
| If you're thinking about enterprisy 50- or 100-line methods, this 
| solution probably sounds awful. Every time you see a variable name in 
| the method, you have to scroll back to the top of the method to see 
| whether it is declared as a self attribute or not. And there are too 
| many potential attributes to keep track of them all in your head.
| And I agree. But that sort of code is not the code that would benefit 
| from this. Instead, think of small methods, say, ten or fifteen lines at 
| most, few enough that you can keep the whole method in view at once. 
| Think of classes with only a few attributes, but where you refer to them 
| repeatedly. Maybe *you* don't feel the need to remove those in-your-face 
| selfs, but can you understand why some people do?


GPG encrypted emails preferred. Key id: 0xD113FCAC3C4E599F
Fingerprint: ED31 791B 2C5C 1613 AF38 8B8A D113 FCAC 3C4E 599F

             »Time flies like an arrow, fruit flies like a Banana.«

More information about the Python-ideas mailing list