views:

101

answers:

4

I've noticed a discrepancy in the way that python parameters are called. In every other language I've dealt with, you either have

foo() 

meaning either no parameters, or as many parameters as you like, or

foo(arg1, arg2,...,argn)

where you pass in the same number of parameters to define the function and call it. In python however, I've noticed that the function definitions, and when the function is called, can have two different parameters sets, this usually consists of:

class foo(object):
    def bar(self, arg1, arg2):
        pass

However, when I want to call the function, all I have to do is:

zoo = foo()
zoo.bar(arg1, arg2)

Where did the self parameter go?

Thank you.

+3  A: 

zoo is the self parameter.

In C++, for example, you get the object passed implicitly as the this pointer. In Python, this parameter is explicit.

Fred Larson
so does that mean I could have done this:zoo = foo()bar(zoo, arg1, arg2), and the dot operator is just sintatic sugar, or is there a namespace collision. I mean, to me anyway, it seams like if you have a system where you can use the dot operator, any method made in a class should know it's being called on itself, or rather, the object it is instantiated from.
Leif Andersen
No. What it means is that there is no keyword like `this` in Python that is implicitly set. Part of the Zen of Python is that "explicit is better than implicit" (try `import this`). In fact, there's nothing special about "self" except convention. You can name the argument anything you want. That's not recommended, though, because it will likely confuse anyone reading your code.
Fred Larson
Does it need to be the first parameter though, could I, for example, make it the last parameter? (I know it's a dumb idea, but would that work)?
Leif Andersen
No, because it's passed by position, not name. It must be the first argument.
Fred Larson
+5  A: 

Where did the self parameter go?

It's in front of the dot when you call the function, i.e. in your case it's zoo.

Note that you can also call the function as foo.bar(zoo, arg1, arg2). Basically in python object.method(arguments) is a shortcut for objects_class.method(object, arguments).

sepp2k
So it is just syntatic sugar. So the actual method is like C does it's method calls, except with namespaces. Right?
Leif Andersen
Not quite. The important thing about the translation from `object.method(arguments)` to `objects_class.method(object, arguments)` is that `objects_class` is determined at runtime. Meaning you don't have to know an object's class when calling a method on it. So you wouldn't be able to go through a python source and replace each occurence of `obj.method()` with `class.method(obj)` because you don't always know the class of obj.
sepp2k
An off-tangent question: couldn't the definition of either `foo` or `zoo` be changed after the creation of `zoo` such that the two calls wouldn't be equivalent anymore? See http://en.wikipedia.org/wiki/Monkey_patching
Mark Ransom
+1  A: 

zoo is implicitly passed as the first parameter in your example.

Mike
A: 

As I remember, "zoo.bar" gives you just an attribute "bar" of object "zoo" that can be called. All magic is done at construction where all methods of class is binded to that object while dictionary of attributes is populated. Consider next example:

zoo = foo()
xbar = zoo.bar
xbar(arg1, arg2)
ony