views:

557

answers:

5

I have been learning Python by following some pygame tutorials.

Therein I found extensive use of the keyword self, and coming from a primarily Java background, I find that I keep forgetting to type self. For example, instead of self.rect.centerx I would type rect.centerx, because, to me, rect is already a member variable of the class.

The Java parallel I can think of for this situation is having to prefix all references to member variables with this.

Am I stuck prefixing all member variables with self, or is there a way to declare them that would allow me to avoid having to do so?

Even if what I am suggesting isn't pythonic, I'd still like to know if it is possible.

I have taken a look at these related SO questions, but they don't quite answer what I am after:

+4  A: 

self is part of the python syntax to access members of objects, so I'm afraid you're stuck with it

Charles Ma
self is a way to tell the access modifier without really using one. +1
Perpetualcoder
+2  A: 

yes, you must always specify self, because explicit is better than implicit, according to python philosophy.

You will also find out that the way you program in python is very different from the way you program in java, hence the use of self tends to decrease because you don't project everything inside the object. Rather, you make larger use of module-level function, which can be better tested.

by the way. I hated it at first, now I hate the opposite. same for indented-driven flow control.

Stefano Borini
"You make larger use of module-level function, which can be better tested" is dubious, and I'd have to strongly disagree. It is true you're not forced to make everything a method (static or not) of some class, regardless of whether it's "logically module-level", but that has nothing to do with self and doesn't have any significant impact on testing one way or the other (for me).
Roger Pate
It arises from my experience. I don't follow it as a mantra every time, but it makes things easier to test if you put anything that does not require member variable access as a separate, independent method. yes, you separate logic from data, which yes, is against OOP, but they are together, just at the module level. I don't give one or the other the "best" mark, it's just a matter of taste. Sometimes I find myself specifying class methods that have nothing to do with the class itself, as they don't touch `self` in any way. So what's the point in having them on the class ?
Stefano Borini
I disagree with both parts of it (it seems I use "non-methods" no more often than in other languages), but "which can be better tested" does imply that one way is superior to the other (is that just how I read it? doesn't seem likely), while I don't find support for that in my experience. Note that I'm not saying you should always use one or the other, I'm only saying methods and non-methods are equally able to be tested.
Roger Pate
yes, of course you can, but the approach is different. An object has a state, a module level method has not. If you find out a test fails while testing a class-level method, two things could have been wrong: 1) the object state at the time of the call 2) the method itself. If you have a stateless module-level method, only case 2 can happen. You moved the setup from the object (where it is black box as the test is concerned, since it's governed by the eventually complex logic inside the object) to the testsuite. You are reducing complexity and keeping tighter control of setup.
Stefano Borini
"If you have a stateless module-level method", what about a stateful module-level method? All you're telling me is that stateless functions are easier to test than stateful ones, and I'll agree with that, but it has nothing to do with methods vs non-methods. View the self parameter as exactly that: just another parameter to the function.
Roger Pate
+5  A: 

Actually self is not a keyword, it's just the name conventionally given to the first parameter of instance methods in Python. And that first parameter can't be skipped, as it's the only mechanism a method has of knowing which instance of your class it's being called on.

Michał Marczyk
+15  A: 

Python requires specifying self. The result is there's never any confusion over what's a member and what's not, even without the full class definition visible. This leads to useful properties, such as: you can't add members which accidentally shadow non-members and thereby break code.

One extreme example: you can write a class without any knowledge of what base classes it might have, and always know whether you are accessing a member or not:

class A(some_function()):
  def f(self):
    self.member = 42
    self.method()

That's the complete code! (some_function returns the type used as a base.)

Another, where the methods of a class are dynamically composed:

class B(object):
  pass

print B()
# <__main__.B object at 0xb7e4082c>

def B_init(self):
  self.answer = 42
def B_str(self):
  return "<The answer is %s.>" % self.answer
# notice these functions require no knowledge of the actual class
# how hard are they to read and realize that "members" are used?

B.__init__ = B_init
B.__str__ = B_str

print B()
# <The answer is 42.>

Remember, both of these examples are extreme and you won't see them every day, nor am I suggesting you should often write code like this, but they do clearly show aspects of self being explicitly required.

Roger Pate
Thank you. This answer hits the spot cos it also explains the benefits of using `self`.
bguiz
+2  A: 

You can use whatever name you want, for example

class test(object):
    def function(this, variable):
        this.variable = variable

or even

class test(object):
    def function(s, variable):
        s.variable = variable

but you are stuck with using a name for the scope.

I do not recommend you use something different to self unless you have a convincing reason, as it would make it alien for experienced pythonistas.

voyager
You can do this, but *don't*! There is no reason to make your code weirder than it needs to be. Yes you can call it anything, but the convention is to call it `self`, and you should follow the convention. It will make your code easier to understand for any experienced Python programmer who looks at it. (This includes you, six months from now, trying to figure out what your old program does!)
steveha