[Python-ideas] Mitigating 'self.' Method Pollution
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
> 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
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
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