14 Replies - 7523 Views - Last Post: 21 August 2012 - 10:24 AM Rate Topic: -----

#1 atraub  Icon User is offline

  • Pythoneer
  • member icon

Reputation: 758
  • View blog
  • Posts: 2,010
  • Joined: 23-December 08

I Also Wish Python Would Kill Its Self!

Post icon  Posted 20 August 2012 - 12:15 PM

*
POPULAR

As I was writing this thread, I saw this one from last year. With the creation of the advanced discussion forum, I figure this would be a great time to move that discussion to the advanced forum and re-open the topic for debate :)

In Python, when you define a class, every method of that class must have "something" as the first parameter representing the object itself. We usually refer to this as "self" but as sepp2k pointed out to me, it can be called anything. Here's an example of self:

class dumbClass():
    def __init__(self,x,y):
        self.x = x
        self.y = y
    def get_x_plus_y(self):
        return self.x + self.y



In the interpreter, we'd do:
>>> x = dumbClass(1,2)
>>> print(x.get_x_plus_y())
3



99% of the time, people make this first parameter 'self', the other 1% of the time you're dealing with someone who is inept or inexperienced. This has been one of the bigger gripes among Python users for years, particularly those with a Java background who fondly remember using 'this'.
Disclaimer: my first language was java

Like so many others, I personally feel that 'self' should be made implicit within classes. From a purely practical perspective, this would be a DRY optimization by removing a variable that should always have the same name and MUST appear at the beginning of every class method. It also will get rid of some cryptic error messages, for example:

class dumbClass():
    def __init__(self,x,y):
        self.x = x
        self.y = y
    def calculateWinning():
        print("not really winning")



When we test that in the interpreter
>>> x = dumbClass(1,2)
>>> x.calculateWinning()
Traceback (most recent call last):
  File "<pyshell#38>", line 1, in <module>
    x.calculateWinning()
TypeError: calculateWinning() takes no arguments (1 given)
>>> 


An inexperienced user might respond with a good ol' "WTF?!". The error claims that I passed in an argument yet I most certainly did not explicitly pass one in. However, the problem is that the value of self is implicitly passed in, and thus I have in fact passed in 1 argument to a function that takes no arguments.

Is it not strange, neigh hypocritical that the object is implicitly passed in yet one of the biggest justifications of self is that explicit is better than implicit? I'm not drinking that koolaid anymore!

Another classic example of a problem associated with this was elegantly displayed by a newer user trying to learn Python:
class Character(object):
    def __init__(self, name, max_health, health, strength, stamina, toHit):
        self.name = name
        self.max_health = max_health
        self.health = health
        self.strength = strength
        self.stamina = stamina
        self.toHit = toHit
    
def recover_health(self, amount):
    if self.health + amount > self.max_health:
        self.health = self.max_health
    else:
        self.health += amount



Notice how the indentation is off, but when he rand the code, it looked like this:
test = Character('John', 10, 10, 10, 10, 10)

recover_health(test, 5)


The code was technically right, but it made it appear that OO in Python really sucks. While this example did come from some code a user recently posted, I assure you that I see similar issues very commonly.

EDIT: Because explicit is better than implicit, I'll also explicitly state: "putting self at the beginning of every method's parameters is annoying and tedious"

However, there are those out there who feel that 'self' is necessary for the good of all mankind. There are those who use the explicit > implicit argument (crap).

Others claim that it won't allow you to dynamically insert methods into classes.
# Define an empty class:
class C:
   pass

# Define a global function:
def meth(myself, arg):
   myself.val = arg
   return myself.val

# Poke the method into the class:
C.meth = meth


I don't buy this one either. As baavgai would say, "Interpreted languages are interpreted". I think that the interpreter could be improved enough to handle this. If it can't, let's be honest, would you really miss this functionality? I wouldn't. I've never used it, I've never even dreamed of a use for it.

This particular blogger also claims that it would destroy decorators. Ehhh, if decorators are a blind spot for Bruce Eckel (who has made one of the most compelling anti-self arguments to date), it's a blind spot for me too, because I rarely use them. Again, I think that Python's interpreter could be improved enough that it can do a little "tree climbing" to see what "self" should be referring to, but I don't know them well enough to intelligently speak on that topic.

What do you guys think? Is 6 characters "self, " enough for people to get their feathers ruffled over? Are we too picky? Is this more of a principles argument? Let's get some "advanced discussion" going :)

This post has been edited by atraub: 20 August 2012 - 01:04 PM


Is This A Good Question/Topic? 5
  • +

Replies To: I Also Wish Python Would Kill Its Self!

#2 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2070
  • View blog
  • Posts: 3,146
  • Joined: 21-June 11

Re: I Also Wish Python Would Kill Its Self!

Posted 20 August 2012 - 02:03 PM

I don't know. I like the conceptual model of my_object.my_method(a,b,c) being equivalent to MyClass.my_method(my_object, a, b, c). I really think that it's easier to explain to newcomers who've never done OO before than a this or self keyword would be.

Regarding explicit vs. implicit, one might argue that a method call like my_object.method(argument) does explicitly mention my_object, so it's not really implicit. That said I definitely agree that it's confusing to refer to my_object as an argument since it does not appear in the argument list - it only makes sense if you mentally translate it to MyClass.method(my_object, x, y, z).

However at least the problem with "number of arguments" in error messages could be fixed by simply giving different error messages when calling functions as methods versus calling them directly. E.g. my_object.my_method() could produce the error message "A function that's called as a method must take at least one argument" (or maybe "must take a self argument") whereas calling MyClass.my_method(my_object) directly would still produce the usual "1 argument, 0 expected" error message. I expect this would require some changes to the byte code format though (I wouldn't expect that method calls and regular function calls are currently distinguishable once compiled to byte code).
Was This Post Helpful? 0
  • +
  • -

#3 atraub  Icon User is offline

  • Pythoneer
  • member icon

Reputation: 758
  • View blog
  • Posts: 2,010
  • Joined: 23-December 08

Re: I Also Wish Python Would Kill Its Self!

Posted 20 August 2012 - 05:12 PM

I don't think that it necessarily makes things easier. Saying something like "objects have attributes; we use 'self' to access those attributes" seems like a nice and easy explanation. It seems harder to explain it as "methods need to have self as the first parameter. Why? Because when an object calls on that method it implicitly passes itself as the first argument" I think most newcomers would give a resounding O_O WTF?!

This post has been edited by atraub: 20 August 2012 - 05:13 PM

Was This Post Helpful? 0
  • +
  • -

#4 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2070
  • View blog
  • Posts: 3,146
  • Joined: 21-June 11

Re: I Also Wish Python Would Kill Its Self!

Posted 20 August 2012 - 05:31 PM

Quote

It seems harder to explain it as "methods need to have self as the first parameter. Why? Because when an object calls on that method it implicitly passes itself as the first argument"


That's not the explanation I had in mind. What I had in mind was "Writing my_object.my_method(arguments) is a shortcut for MyClass.my_method(my_object, arguments)". I don't think that formulation would sound scary to most people.
Was This Post Helpful? 0
  • +
  • -

#5 atraub  Icon User is offline

  • Pythoneer
  • member icon

Reputation: 758
  • View blog
  • Posts: 2,010
  • Joined: 23-December 08

Re: I Also Wish Python Would Kill Its Self!

Posted 20 August 2012 - 06:31 PM

If it were me, I don't think I'd find that as a very satisfying answer. Why not simply have the attributes of a class accessible without a method needing to pass its container as an argument? It feels more like laziness on the side of Guido to me. If self were implicit, no one would ever clamor to have it made explicit.

EDIT:
It all feels overly cyclical.

When using Python, a method needs to include 'self' as a parameter in its definition so that when an object calls on said method, that method will have that object passed in as the first argument, so that the method will then have access to the attributes of the very object that is calling that method! :dontgetit:

This post has been edited by atraub: 20 August 2012 - 06:48 PM

Was This Post Helpful? 0
  • +
  • -

#6 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4404
  • View blog
  • Posts: 7,646
  • Joined: 08-June 10

Re: I Also Wish Python Would Kill Its Self!

Posted 20 August 2012 - 07:28 PM

I'll chime in as a non-pythoner. My only experience with Python has been reading a book and doing some of the samples. I've never used it for any application beyond examples. So take this for what its worth:

If every class-level method must include a self parameter, and it must always be in the same position, then to me it's a complete no-brainer that it should be implicit rather than explicit. Otherwise, it's just boilerplate, and I thought that was something that Python tended to avoid. Having an implicit property of a class that pointed to itself, or even a keyword that did the same, would be a simple way to provide similar functionality minus the boilerplate.

On the other hand, the question would be "how do we implement this without breaking a metric ton of existing code?" I understand that Python isn't totally averse to breaking changes, what with Python 3 doing just that, but I would think they'd want to avoid doing that again, such a short time from the last one. I suppose there would be some way to implement some kind of directive (similar to VB.NET's Option Strict) to tell the interpreter whether or not it should create this implicit property and not implicitly pass the object reference as the first parameter, with the default behavior being set to "Off". That way, old code could run, and allow new code to opt in to this behavior.
Was This Post Helpful? 0
  • +
  • -

#7 atraub  Icon User is offline

  • Pythoneer
  • member icon

Reputation: 758
  • View blog
  • Posts: 2,010
  • Joined: 23-December 08

Re: I Also Wish Python Would Kill Its Self!

Posted 20 August 2012 - 07:33 PM

View PostCurtis Rutland, on 20 August 2012 - 10:28 PM, said:

If every class-level method must include a self parameter, and it must always be in the same position, then to me it's a complete no-brainer that it should be implicit rather than explicit.
This!


View PostCurtis Rutland, on 20 August 2012 - 10:28 PM, said:

On the other hand, the question would be "how do we implement this without breaking a metric ton of existing code?" I understand that Python isn't totally averse to breaking changes, what with Python 3 doing just that, but I would think they'd want to avoid doing that again, such a short time from the last one.

I was thinking this would be a Python 4 thing ;)

This post has been edited by atraub: 20 August 2012 - 07:36 PM

Was This Post Helpful? 0
  • +
  • -

#8 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4404
  • View blog
  • Posts: 7,646
  • Joined: 08-June 10

Re: I Also Wish Python Would Kill Its Self!

Posted 20 August 2012 - 07:36 PM

Understood, but does Python 4 have to be as breaking as Python 3 was? I mean, generally speaking, language updates are iterative. They tend to add and extend, unless things are fundamentally broken. I realize that this is a completely different line of discussion, though.
Was This Post Helpful? 0
  • +
  • -

#9 atraub  Icon User is offline

  • Pythoneer
  • member icon

Reputation: 758
  • View blog
  • Posts: 2,010
  • Joined: 23-December 08

Re: I Also Wish Python Would Kill Its Self!

Posted 20 August 2012 - 07:41 PM

I'll personally write a conversion tool.

Posted Image

This post has been edited by atraub: 20 August 2012 - 07:42 PM

Was This Post Helpful? 0
  • +
  • -

#10 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2070
  • View blog
  • Posts: 3,146
  • Joined: 21-June 11

Re: I Also Wish Python Would Kill Its Self!

Posted 20 August 2012 - 08:06 PM

View PostCurtis Rutland, on 21 August 2012 - 04:28 AM, said:

If every class-level method must include a self parameter


A function written in a class does not have to take any parameters. This is perfectly legal:

class Foo:
  def foo():
    return 42

Foo.foo() # returns 42



However you won't be able to call the function as a method (i.e. my_foo_object.foo()) unless it takes at least one argument (or you use the @staticmethod decorator).
Was This Post Helpful? 0
  • +
  • -

#11 atraub  Icon User is offline

  • Pythoneer
  • member icon

Reputation: 758
  • View blog
  • Posts: 2,010
  • Joined: 23-December 08

Re: I Also Wish Python Would Kill Its Self!

Posted 20 August 2012 - 08:08 PM

There's no reason to put that function at the class level rather than module level.

EDIT:
It looks weird and it blurs the distinction between modules and classes.

EDIT 2:
Even uglier...
#mod1.py
class Foo:
  def foo():
    return 42

#test.py
import mod1

print(mod1.Foo.foo())



This post has been edited by atraub: 20 August 2012 - 08:30 PM

Was This Post Helpful? 0
  • +
  • -

#12 cfoley  Icon User is offline

  • Cabbage
  • member icon

Reputation: 1933
  • View blog
  • Posts: 4,015
  • Joined: 11-December 07

Re: I Also Wish Python Would Kill Its Self!

Posted 20 August 2012 - 11:57 PM

Another non-Pythoner chiming in here. The self argument might have its roots in Python being a multi-paradigm language. From the little I've played with it, the functional aspects seem to work a little smoother than the OO parts and my naive guess is that the language was designed to favour a functional style over an OO style, while still allowing the best from both worlds.

Certainly from a functional point if view, explicitly naming the self argument seems to make sense. You can reason about referential transparency, etc. This is not to say that you couldn't if self was implied, but this latter fact seems to be ignored when Functional Programmers comment on the shortcomings of OO languages.
Was This Post Helpful? 0
  • +
  • -

#13 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2233
  • View blog
  • Posts: 9,401
  • Joined: 29-May 08

Re: I Also Wish Python Would Kill Its Self!

Posted 21 August 2012 - 03:50 AM

To me, it looks if share some of the traits of SmallTalk.

Isn't the self parameter akin the sender parameter in .net, being the sender of the message, or raiser of the event.

self being a reference to the instance of this class type that is being called on, in .net being this. or Me.(vb.net)

Also how would you refer to shared / static methods? Or base class methods?

This post has been edited by AdamSpeight2008: 21 August 2012 - 03:52 AM

Was This Post Helpful? 0
  • +
  • -

#14 ishkabible  Icon User is offline

  • spelling expret
  • member icon




Reputation: 1622
  • View blog
  • Posts: 5,709
  • Joined: 03-August 09

Re: I Also Wish Python Would Kill Its Self!

Posted 21 August 2012 - 05:50 AM

static member functions allow for functionality that only an open function can provide without breaking encapsulation so there is a reason to have them. a 'static' keyword, like many other languages have, to denote this might be the ticket and then adding the implicit self parameter...or if we wanted to break less code we would have a 'method' keyword instead of 'def' for declaring a method; both would still work but 'method' would add the implicit parameter.
Was This Post Helpful? 2
  • +
  • -

#15 atraub  Icon User is offline

  • Pythoneer
  • member icon

Reputation: 758
  • View blog
  • Posts: 2,010
  • Joined: 23-December 08

Re: I Also Wish Python Would Kill Its Self!

Posted 21 August 2012 - 10:24 AM

I love the idea of explicitly calling them methods!!
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1