469,290 Members | 1,887 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,290 developers. It's quick & easy.

Why the 'self' argument?

Hello,

I'm a newbie Python user, a systems administrator - I've been trying
to switch from Perl to Python for administrative tasks - and one thing
I cannot understand so far is why I need the special 'self' (or anything
esle) argument in class method definitions. I might have missed an
explanation in the docs, a quick Google search did not help. Is there
somewhere on the web you could direct me to?

Thanks,

--
Grzegorz Staniak <gs******@zagiel.com.pl>
Jul 18 '05 #1
37 16660
In article <vl************@news.supernews.com>, John Roth wrote:
Technically, it would be possible to make "self" a reserved
word, and not have to put it in the method declaration.
However, there are a lot of people who use something other than
the word "self," so that would break existing code.


It would also make the language more complex and irregular.

--
Grant Edwards grante Yow! Could I have a drug
at overdose?
visi.com
Jul 18 '05 #2
Grzegorz Staniak wrote:
Hello,

I'm a newbie Python user, a systems administrator - I've been trying
to switch from Perl to Python for administrative tasks - and one thing
I cannot understand so far is why I need the special 'self' (or anything
esle) argument in class method definitions. I might have missed an
explanation in the docs, a quick Google search did not help. Is there
somewhere on the web you could direct me to?


This entry of the Python FAQ:

http://www.python.org/doc/faq/genera...ions-and-calls

-- Gerhard

Jul 18 '05 #3
On Fri, Sep 05, 2003 at 01:58:41PM +0000, Grzegorz Staniak wrote:
Hello,

I'm a newbie Python user, a systems administrator - I've been trying
to switch from Perl to Python for administrative tasks - and one thing
I cannot understand so far is why I need the special 'self' (or anything
esle) argument in class method definitions. I might have missed an
explanation in the docs, a quick Google search did not help. Is there
somewhere on the web you could direct me to?

Thanks,

--
Grzegorz Staniak <gs******@zagiel.com.pl>
--
http://mail.python.org/mailman/listinfo/python-list


The first argument in a class method is a reference to that class itself. It is
same as "this" pointer in c++ and java. Using this argument you can access the
class variables. ex:

class test:
def __init__(self,arg1,arg2): #this acts as class constructor
self.name=arg1
self.value=arg2
def changeName(self,newName): #here we change the name class variable
self.name=newName
..........and so on

regards
Vivek Kumar

Jul 18 '05 #4

"Grant Edwards" <gr****@visi.com> wrote in message
news:3f*********************@newsreader.visi.com.. .
In article <vl************@news.supernews.com>, John Roth wrote:
Technically, it would be possible to make "self" a reserved
word, and not have to put it in the method declaration.
However, there are a lot of people who use something other than
the word "self," so that would break existing code.
It would also make the language more complex and irregular.


How?

John Roth

--
Grant Edwards grante Yow! Could I have a drug at overdose?
visi.com

Jul 18 '05 #5
In article <vl************@news.supernews.com>, John Roth wrote:

"Grant Edwards" <gr****@visi.com> wrote in message
news:3f*********************@newsreader.visi.com.. .
In article <vl************@news.supernews.com>, John Roth wrote:
> Technically, it would be possible to make "self" a reserved
> word, and not have to put it in the method declaration.
> However, there are a lot of people who use something other than
> the word "self," so that would break existing code.


It would also make the language more complex and irregular.


How?


1) It would add a reserved word.

2) It would mean that there's some sort of difference between
a function and a method.

--
Grant Edwards grante Yow! I have a TINY BOWL in
at my HEAD
visi.com
Jul 18 '05 #6
vi***@cs.unipune.ernet.in wrote:
...
The first argument in a class method is a reference to that class itself.


Yes, that's what defines CLASS methods (as opposed to ordinary, or
INSTANCE, methods). But the original poster was not asking about class
methods, and you're not giving any examples of them -- I only see
instance methods. I suspect a terminology problem -- you may be using
the term "class method" in a way that is totally inappropriate to
Python, where classes are first-level objects.
So -- in Python, you see...:

To make a class method you have to call on the classmethod built-in. E.g.:

class Example(object):

def instmeth(self): print 'Instance method of', self

def clasmeth(cls): print 'Class method of', cls
clasmeth = classmethod(clasmeth)

inst = Example()
Now you can call:

inst.instmeth()

or:

inst.clasmeth()
Example.clasmeth()

(both of these do exactly the same thing), but NOT:

Example.instmeth()

since an INSTANCE method, differently from a CLASS method,
needs to be passed the instance as the first argument, either
implicitly (by CALLING it on the instance) or explicitly
by passing it when calling the method on the class, as in:

Example.instmeth(inst)
Alex

Jul 18 '05 #7

"Grant Edwards" <gr****@visi.com> wrote in message
news:3f*********************@newsreader.visi.com.. .
In article <vl************@news.supernews.com>, John Roth wrote:

"Grant Edwards" <gr****@visi.com> wrote in message
news:3f*********************@newsreader.visi.com.. .
In article <vl************@news.supernews.com>, John Roth wrote:

> Technically, it would be possible to make "self" a reserved
> word, and not have to put it in the method declaration.
> However, there are a lot of people who use something other than
> the word "self," so that would break existing code.

It would also make the language more complex and irregular.
How?


1) It would add a reserved word.


So? For most people, self *is* a reserved word anyway. A lot of
novices think it is. Making it official simplifies things, IMO.
2) It would mean that there's some sort of difference between
a function and a method.
I don't understand your point. There is currently a difference
between a function and a method that could be eliminated by
making self a reserved word and removing it from the method
header. Or have you never tried to invoke a method from the
wrong context and gotten the "unbound method" error?

There's no reason why a function in the module space couldn't
use self to refer to the module. It would simplify things by
removing much of the need for the global keyword.

John Roth
--
Grant Edwards

Jul 18 '05 #8

"Mel Wilson" <mw*****@the-wire.com> wrote in message
news:qpOW/ks/Kn*******@the-wire.com...
In article <vl************@news.supernews.com>,
"John Roth" <ne********@jhrothjr.com> wrote:
"Grant Edwards" <gr****@visi.com> wrote in message
news:3f*********************@newsreader.visi.com. ..
In article <vl************@news.supernews.com>, John Roth wrote:
>
> "Grant Edwards" <gr****@visi.com> wrote in message
> news:3f*********************@newsreader.visi.com.. .
2) It would mean that there's some sort of difference between
a function and a method.
I don't understand your point. There is currently a difference
between a function and a method that could be eliminated by
making self a reserved word and removing it from the method
header. Or have you never tried to invoke a method from the
wrong context and gotten the "unbound method" error?


There's no difference in the sense that a method is
simply a function whose first parameter refers to the class
instance to be worked on. No magic words, no "undeclared"
parameters. It means that in my demo code in limitcases.py
(somewhere in the newsgroup lately) I can say

limitcases.Lowest.__str__ = lambda x: "-Infinity"

to give the Lowest class a new method sans ennuis.


But why do it that way? Neither Java nor Ruby require
giving the instance a name. Hence my comment that requiring
it is more complex than not requiring it.

John Roth
Regards. Mel.

Jul 18 '05 #9

"Grzegorz Staniak" <gs******@inka.zagiel.pl>
I'm a newbie Python user, a systems administrator - I've been trying
to switch from Perl to Python for administrative tasks - and one thing
I cannot understand so far is why I need the special 'self' (or anything
esle) argument in class method definitions.


You probably do not mean "class methods"; this a technical term in OOP.

The Python class basics are *very* similar to the implementation of Perl
classes!!
You should not have much problems....

Kindly
Michael P
Jul 18 '05 #10
In article <vl************@news.supernews.com>, John Roth wrote:
There's no difference in the sense that a method is simply a
function whose first parameter refers to the class instance to
be worked on. No magic words, no "undeclared" parameters. It
means that in my demo code in limitcases.py (somewhere in the
newsgroup lately) I can say

limitcases.Lowest.__str__ = lambda x: "-Infinity"

to give the Lowest class a new method sans ennuis.
But why do it that way?


So that there's no difference between a function and a method.

Simplicity and orthogonality are good things -- despite what
C++ proponents thing.
Neither Java nor Ruby require giving the instance a name.
So?

Personally I don't like invisible, implied, automatic stuff
like that.

Can't stand automatic transmissions either -- the damn things
have no idea what's ahead, and always seem to be in the wrong
gear at critical moments.
Hence my comment that requiring it is more complex than not
requiring it.


No, it's more complex the Java/Ruby way, since you have to have
two sets of rules for what a name means depending on whether
you're inside a "normal" function or a method. In Python
there's just one set of rules -- mostly.

I have enough trouble remembering how the stuff I design works. ;)

I don't want to have to keep track of more scoping/name-space
rules than absolutely necessary.

--
Grant Edwards grante Yow! Intra-mural sports
at results are filtering
visi.com through th' plumbing...
Jul 18 '05 #11
On Fri, 5 Sep 2003 22:51:10 +0200, "Michael Peuser" <mp*****@web.de> wrote:

"Grzegorz Staniak" <gs******@inka.zagiel.pl>
I'm a newbie Python user, a systems administrator - I've been trying
to switch from Perl to Python for administrative tasks - and one thing
I cannot understand so far is why I need the special 'self' (or anything
esle) argument in class method definitions.


You probably do not mean "class methods"; this a technical term in OOP.

I suspect the OP meant "class (method definitions)," not "(class method)" definitions." ;-)

Re "self," there must be a FAQ entry, but I'm too lazy to look for it.

Regards,
Bengt Richter
Jul 18 '05 #12

"Grant Edwards" <gr****@visi.com> wrote in message
news:3f*********************@newsreader.visi.com.. .
In article <vl************@news.supernews.com>, John Roth wrote:
There's no difference in the sense that a method is simply a
function whose first parameter refers to the class instance to
be worked on. No magic words, no "undeclared" parameters. It
means that in my demo code in limitcases.py (somewhere in the
newsgroup lately) I can say

limitcases.Lowest.__str__ = lambda x: "-Infinity"

to give the Lowest class a new method sans ennuis.
But why do it that way?


So that there's no difference between a function and a method.

Simplicity and orthogonality are good things -- despite what
C++ proponents thing.
Neither Java nor Ruby require giving the instance a name.


So?

Personally I don't like invisible, implied, automatic stuff
like that.

Can't stand automatic transmissions either -- the damn things
have no idea what's ahead, and always seem to be in the wrong
gear at critical moments.
Hence my comment that requiring it is more complex than not
requiring it.


No, it's more complex the Java/Ruby way, since you have to have
two sets of rules for what a name means depending on whether
you're inside a "normal" function or a method. In Python
there's just one set of rules -- mostly.


As I said earlier, it's quite possible to define it so that there
is always an instance of some kind; whether that's an instance
a class or the module itself.
I have enough trouble remembering how the stuff I design works. ;)

I don't want to have to keep track of more scoping/name-space
rules than absolutely necessary.
I think my comments have shown that you can reduce the
amount of scoping / name space rules noticably.

John Roth
--
Grant Edwards grante Yow! Intra-mural sports at results are filtering
visi.com through th' plumbing...

Jul 18 '05 #13

"Michael Peuser" <mp*****@web.de> wrote in message
news:bj*************@news.t-online.com...

"Grzegorz Staniak" <gs******@inka.zagiel.pl>
I'm a newbie Python user, a systems administrator - I've been trying
to switch from Perl to Python for administrative tasks - and one thing
I cannot understand so far is why I need the special 'self' (or anything
esle) argument in class method definitions.
You probably do not mean "class methods"; this a technical term in OOP.

The Python class basics are *very* similar to the implementation of Perl
classes!!
You should not have much problems....


Actually, I think he *does* mean "class methods." They are new in 2.2
after all, and I missed the qualification the first time around.

John Roth
Kindly
Michael P

Jul 18 '05 #14
In article <vl************@news.supernews.com>, John Roth wrote:
So that there's no difference between a function and a method.

Simplicity and orthogonality are good things -- despite what
C++ proponents thing.
> Hence my comment that requiring it is more complex than not
> requiring it.
No, it's more complex the Java/Ruby way, since you have to have
two sets of rules for what a name means depending on whether
you're inside a "normal" function or a method. In Python
there's just one set of rules -- mostly.


As I said earlier, it's quite possible to define it so that there
is always an instance of some kind; whether that's an instance
a class or the module itself.


I don't follow. You're talking about defining a keyword that
always refers to the first parameter passed to a function? And
the declared parameters would refer to the 2nd through Nth
parameters? What if the keyword isn't used in the function
definition, then do the delcared parameters refer to the 1st
through Nth?
I think my comments have shown that you can reduce the amount
of scoping / name space rules noticably.


Compared to what? It sure sounds like you're introducing more
rules than there are now. How would you propose reducing the
number of rules?

--
Grant Edwards grante Yow! Somewhere in Tenafly,
at New Jersey, a chiropractor
visi.com is viewing "Leave it to
Beaver"!
Jul 18 '05 #15

"Grant Edwards" <gr****@visi.com> wrote in message
news:3f*********************@newsreader.visi.com.. .
In article <vl************@news.supernews.com>, John Roth wrote:
So that there's no difference between a function and a method.

Simplicity and orthogonality are good things -- despite what
C++ proponents thing.

> Hence my comment that requiring it is more complex than not
> requiring it.

No, it's more complex the Java/Ruby way, since you have to have
two sets of rules for what a name means depending on whether
you're inside a "normal" function or a method. In Python
there's just one set of rules -- mostly.
As I said earlier, it's quite possible to define it so that there
is always an instance of some kind; whether that's an instance
a class or the module itself.


I don't follow. You're talking about defining a keyword that
always refers to the first parameter passed to a function? And
the declared parameters would refer to the 2nd through Nth
parameters? What if the keyword isn't used in the function
definition, then do the delcared parameters refer to the 1st
through Nth?


When Python invokes a function, it binds the operands in the
function call to the identifiers named in the function / method
header. If this is a method, it binds the instance (which is not
in the invocation parameter list, btw.) to the first
parameter in the method header.

If you make "self" a reserved word, then all it has to do
is bind the instance to "self," rather than the first identifier
in the parameter list.

In current python, there are two classes of functions (module
level and embedded) and three classes of methods (instance,
class and static.) Instance methods get the current instance,
class methods get the class object as the instance, and the other
three categories get nothing.

As a separate suggestion, I'd have Python bind the module
object to "self" for module functions and static methods. I
haven't figured out what I want done with embedded methods
and unbound methods yet. Notice that this eliminates the
need for the global statement for module functions - all
identifiers are accessible for rebinding through "self."
I think my comments have shown that you can reduce the amount
of scoping / name space rules noticably.


Compared to what? It sure sounds like you're introducing more
rules than there are now. How would you propose reducing the
number of rules?


If you don't have to write "self" as the first parameter of a method,
that reduces the complexity. Everything else remains the same.

John Roth
--
Grant Edwards grante Yow! Somewhere in Tenafly, at New Jersey, a chiropractor visi.com is viewing "Leave it to
Beaver"!

Jul 18 '05 #16
On Fri, 5 Sep 2003 20:15:00 -0400, "John Roth" <ne********@jhrothjr.com> wrote:
[...]
If you don't have to write "self" as the first parameter of a method,
that reduces the complexity. Everything else remains the same.

Except for cases where two self-parameters are visible at the same time,
and both are used in an inner scope and must be distinguished by giving
them different names. ISTM you'd have to turn off some dynamic capabilities
of python to make "self" implicit. (An example came up in a past discussion,
some time ago).

Regards,
Bengt Richter
Jul 18 '05 #17

"Bengt Richter" <bo**@oz.net> wrote in message
news:bj**********@216.39.172.122...
On Fri, 5 Sep 2003 20:15:00 -0400, "John Roth" <ne********@jhrothjr.com> wrote: [...]
If you don't have to write "self" as the first parameter of a method,
that reduces the complexity. Everything else remains the same.
Except for cases where two self-parameters are visible at the same time,
and both are used in an inner scope and must be distinguished by giving
them different names. ISTM you'd have to turn off some dynamic

capabilities of python to make "self" implicit. (An example came up in a past discussion, some time ago).
You could still give them different names. The proposal is to eliminate
the need to specify "self" in the method header, not in the code in the
method body. That's a different issue, and I don't know of any language
that manages to do it consistently.

John Roth
Regards,
Bengt Richter

Jul 18 '05 #18
On 05 Sep 2003 15:55:34 GMT, Grant Edwards wrote:
In article <vl************@news.supernews.com>, John Roth wrote:

"Grant Edwards" <gr****@visi.com> wrote in message
news:3f*********************@newsreader.visi.com.. .
In article <vl************@news.supernews.com>, John Roth wrote:

> Technically, it would be possible to make "self" a reserved
> word, and not have to put it in the method declaration.
> However, there are a lot of people who use something other than
> the word "self," so that would break existing code.

It would also make the language more complex and irregular.
How?

1) It would add a reserved word. 2) It would mean that there's some sort of difference between
a function and a method.


There *is* a difference between a function and a method (a method
/contains/ a function), unless you just mean that they're both
callable (which is not necessarily true in other languages)

But you can't define methods, you can only define functions (Python
makes methods by "magic"), so the "self" parameter is no different
than any other...it's pretty weird to suggest that it should be
treated differently. Why not treat the 5th parameter specially?

--
Just because we Lisp programmers are better than everyone else is no
excuse for us to be arrogant. -- Erann Gat

(setq reply-to
(concatenate 'string "Paul Foley " "<mycroft" '(#\@) "actrix.gen.nz>"))
Jul 18 '05 #19
Hi,

the answer is in python FAQ:

http://python.org/doc/faq/general.ht...ions-and-calls

--

=*= Lukasz Pankowski =*=
Jul 18 '05 #20
Grant Edwards wrote:
...
Hence my comment that requiring it is more complex than not
requiring it.


No, it's more complex the Java/Ruby way, since you have to have
two sets of rules for what a name means depending on whether
you're inside a "normal" function or a method. In Python
there's just one set of rules -- mostly.


Java and Ruby have no "normal functions" -- just methods. Ruby
has what may LOOK like ordinary functions, but they're methods
of the module object...
Alex

Jul 18 '05 #21

"John Roth" <ne********@jhrothjr.com>
You could still give them different names. The proposal is to eliminate
the need to specify "self" in the method header, not in the code in the
method body. That's a different issue, and I don't know of any language
that manages to do it consistently.


You'll run into all the problems known from the Pascal with-statement. And
that's not only a readability matter.

Kindly
Michael P
Jul 18 '05 #22
>>>>> "Michael" == Michael Peuser <mp*****@web.de> writes:

John> You could still give them different names. The proposal is to
John> eliminate the need to specify "self" in the method header, not in
John> the code in the method body. That's a different issue, and I don't
John> know of any language that manages to do it consistently.

Michael> You'll run into all the problems known from the Pascal
Michael> with-statement. And that's not only a readability matter.

I think John is talking about a syntax that have the self formal argument
implicit, but the self actual argument explicit. Something like this:

class foo:
def __init__(msg):
self.msg = str(msg)
def f(arg):
print self.msg + ', ' + str(arg)
v = foo('hello')
v.f('world') # equivalent to foo.f(v, 'world')

which would be equivalent to the current Python

class foo:
def __init__(self, msg):
self.msg = str(msg)
def f(self, arg):
print self.msg + ', ' + str(arg)
v = foo('hello')
v.f('world') # equivalent to foo.f(v, 'world')

If that's really what he mean, he is correct in every word: the only change
is that you treat self as a reserved word, and the real road-block is that
everybody think that self is not reserved. There is a problem that you can
no longer define normal function in a class, though. The interpretor would
think that the function is a method.

Regards,
Isaac.
Jul 18 '05 #23
On Fri, 5 Sep 2003 20:15:00 -0400, "John Roth" <ne********@jhrothjr.com> wrote:

"Grant Edwards" <gr****@visi.com> wrote in message
news:3f*********************@newsreader.visi.com. ..
In article <vl************@news.supernews.com>, John Roth wrote:
>> So that there's no difference between a function and a method.
>>
>> Simplicity and orthogonality are good things -- despite what
>> C++ proponents thing.
>>
>> > Hence my comment that requiring it is more complex than not
>> > requiring it.
>>
>> No, it's more complex the Java/Ruby way, since you have to have
>> two sets of rules for what a name means depending on whether
>> you're inside a "normal" function or a method. In Python
>> there's just one set of rules -- mostly.
>
> As I said earlier, it's quite possible to define it so that there
> is always an instance of some kind; whether that's an instance
> a class or the module itself.


I don't follow. You're talking about defining a keyword that
always refers to the first parameter passed to a function? And
the declared parameters would refer to the 2nd through Nth
parameters? What if the keyword isn't used in the function
definition, then do the delcared parameters refer to the 1st
through Nth?


When Python invokes a function, it binds the operands in the
function call to the identifiers named in the function / method
header. If this is a method, it binds the instance (which is not
in the invocation parameter list, btw.) to the first
parameter in the method header.

If you make "self" a reserved word, then all it has to do
is bind the instance to "self," rather than the first identifier
in the parameter list.

In current python, there are two classes of functions (module
level and embedded) and three classes of methods (instance,
class and static.) Instance methods get the current instance,
class methods get the class object as the instance, and the other
three categories get nothing.

As a separate suggestion, I'd have Python bind the module
object to "self" for module functions and static methods. I
haven't figured out what I want done with embedded methods
and unbound methods yet. Notice that this eliminates the
need for the global statement for module functions - all
identifiers are accessible for rebinding through "self."
> I think my comments have shown that you can reduce the amount
> of scoping / name space rules noticably.


Compared to what? It sure sounds like you're introducing more
rules than there are now. How would you propose reducing the
number of rules?


If you don't have to write "self" as the first parameter of a method,
that reduces the complexity. Everything else remains the same.


Will this still be possible?
def foo(*args): print args ... class A(object): pass ... class B(A): pass ... a = A()
b = B()
A.bar = foo
b.bar('howdy') (<__main__.B object at 0x00906E70>, 'howdy') a.bar('howdy') (<__main__.A object at 0x00907170>, 'howdy') foo('howdy') ('howdy',)
A.bar('hello') Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: unbound method foo() must be called with A instance as first argument (got str instan
ce instead) A.__dict__['bar']('hello')

('hello',)

I.e., the method-vs-function distinction is a matter of how you access the function dynamically,
not how you define it. There is no static distinction in functionality, AFAIK (though I guess
there could possibly be some speculative optimizations).

(The above doesn't even get into the multiple name issues I alluded to).

Regards,
Bengt Richter
Jul 18 '05 #24
Two reasons I cringe when I see self as the first parameter of method
declarations (i.e. "def methodname(self, ...)" (I don't mind self in
the method body)):

1) I abhor redundancy. My first impression on seeing self as the first
parameter of all method declarations is that it seems redundant -- it
probably isn't technically, but it looks redundant: (self, (self,
(self, (self, ...

2) The number of parameters in the method call is one less than the
number of parameters in the method declaration. I'm annoyed when I see
this because I want the rules of the language to be obvious (in this
case, a one-to-one mapping). I would be embarassed to have to explain
this to a beginning programmer.

(I do like how Python indenting indicates blocks, however)
Jul 18 '05 #25
Jonathan Aquino wrote:
Two reasons I cringe when I see self as the first parameter of method
declarations (i.e. "def methodname(self, ...)" (I don't mind self in
the method body)):

1) I abhor redundancy. My first impression on seeing self as the first
parameter of all method declarations is that it seems redundant -- it
probably isn't technically, but it looks redundant: (self, (self,
(self, (self, ...

2) The number of parameters in the method call is one less than the
number of parameters in the method declaration. I'm annoyed when I see
this because I want the rules of the language to be obvious (in this
case, a one-to-one mapping). I would be embarassed to have to explain
this to a beginning programmer.

(I do like how Python indenting indicates blocks, however)


I agree, it's not logical. I'm learning Python at the moment, and like
it very much. This "self" thing seems to be the only odd feature, it
feels like the whole class feature was added later. The Quick Python
book says that Python was designed to be object oriented from the ground
up. Is it true?

Harri

Jul 18 '05 #26
In article <Uc*****************@reader1.news.jippii.net>, Harri Pesonen wrote:
I agree, it's not logical. I'm learning Python at the moment, and like
it very much. This "self" thing seems to be the only odd feature,
It seemed quite natural to me, but perhaps that's because I'd
used other languages that worked the same way. Coming from
Modula-3 and Smalltalk, the way classes worked in Python seemed
quite intuitive.

OTOH, C++ seems like a real non-intuitive mess to me.
it feels like the whole class feature was added later.
Why?
The Quick Python book says that Python was designed to be
object oriented from the ground up. Is it true?


--
Grant Edwards grante Yow! ... I think I'm
at having an overnight
visi.com sensation right now!!
Jul 18 '05 #27

"Bengt Richter" <bo**@oz.net> wrote in message
news:bj**********@216.39.172.122...
On Fri, 5 Sep 2003 20:15:00 -0400, "John Roth" <ne********@jhrothjr.com> wrote:

"Grant Edwards" <gr****@visi.com> wrote in message
news:3f*********************@newsreader.visi.com. ..
In article <vl************@news.supernews.com>, John Roth wrote:

>> So that there's no difference between a function and a method.
>>
>> Simplicity and orthogonality are good things -- despite what
>> C++ proponents thing.
>>
>> > Hence my comment that requiring it is more complex than not
>> > requiring it.
>>
>> No, it's more complex the Java/Ruby way, since you have to have
>> two sets of rules for what a name means depending on whether
>> you're inside a "normal" function or a method. In Python
>> there's just one set of rules -- mostly.
>
> As I said earlier, it's quite possible to define it so that there
> is always an instance of some kind; whether that's an instance
> a class or the module itself.

I don't follow. You're talking about defining a keyword that
always refers to the first parameter passed to a function? And
the declared parameters would refer to the 2nd through Nth
parameters? What if the keyword isn't used in the function
definition, then do the delcared parameters refer to the 1st
through Nth?
When Python invokes a function, it binds the operands in the
function call to the identifiers named in the function / method
header. If this is a method, it binds the instance (which is not
in the invocation parameter list, btw.) to the first
parameter in the method header.

If you make "self" a reserved word, then all it has to do
is bind the instance to "self," rather than the first identifier
in the parameter list.

In current python, there are two classes of functions (module
level and embedded) and three classes of methods (instance,
class and static.) Instance methods get the current instance,
class methods get the class object as the instance, and the other
three categories get nothing.

As a separate suggestion, I'd have Python bind the module
object to "self" for module functions and static methods. I
haven't figured out what I want done with embedded methods
and unbound methods yet. Notice that this eliminates the
need for the global statement for module functions - all
identifiers are accessible for rebinding through "self."
> I think my comments have shown that you can reduce the amount
> of scoping / name space rules noticably.

Compared to what? It sure sounds like you're introducing more
rules than there are now. How would you propose reducing the
number of rules?


If you don't have to write "self" as the first parameter of a method,
that reduces the complexity. Everything else remains the same.


Will this still be possible?
>>> def foo(*args): print args ... >>> class A(object): pass ... >>> class B(A): pass ... >>> a = A()
>>> b = B()
>>> A.bar = foo
>>> b.bar('howdy') (<__main__.B object at 0x00906E70>, 'howdy') >>> a.bar('howdy') (<__main__.A object at 0x00907170>, 'howdy') >>> foo('howdy') ('howdy',)
>>> A.bar('hello') Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: unbound method foo() must be called with A instance as first

argument (got str instan ce instead) >>> A.__dict__['bar']('hello')
('hello',)

I.e., the method-vs-function distinction is a matter of how you access the

function dynamically, not how you define it. There is no static distinction in functionality, AFAIK (though I guess there could possibly be some speculative optimizations).
It certainly needs to be. One of the reasons I haven't written a PEP is
that providing an instance to an unbound method is a case I don't have
a clear and simple answer to at the moment.
(The above doesn't even get into the multiple name issues I alluded to).

I don't think the multiple name issues are relevant - that has to do with
how the functions/methods are invoked, rather than what's in the header.)

John Roth
Regards,
Bengt Richter

Jul 18 '05 #28

"Harri Pesonen" <fu****@sci.fi> wrote in message
news:Uc*****************@reader1.news.jippii.net.. .
Jonathan Aquino wrote:
Two reasons I cringe when I see self as the first parameter of method
declarations (i.e. "def methodname(self, ...)" (I don't mind self in
the method body)):

1) I abhor redundancy. My first impression on seeing self as the first
parameter of all method declarations is that it seems redundant -- it
probably isn't technically, but it looks redundant: (self, (self,
(self, (self, ...

2) The number of parameters in the method call is one less than the
number of parameters in the method declaration. I'm annoyed when I see
this because I want the rules of the language to be obvious (in this
case, a one-to-one mapping). I would be embarassed to have to explain
this to a beginning programmer.

(I do like how Python indenting indicates blocks, however)
I agree, it's not logical. I'm learning Python at the moment, and like
it very much. This "self" thing seems to be the only odd feature, it
feels like the whole class feature was added later. The Quick Python
book says that Python was designed to be object oriented from the ground
up. Is it true?


I'm not sure; someone who knows the history back to the beginning
would have to say. However, there's a difference between "from the
ground up," which is certainly true, and "from the beginning" which
may or may not be true.

John Roth

Harri

Jul 18 '05 #29

"Isaac To" <kk**@csis.hku.hk> wrote in message
news:7i************@enark.csis.hku.hk...
class foo:
def __init__(msg):
self.msg = str(msg)
def f(arg):
print self.msg + ', ' + str(arg)
v = foo('hello')
v.f('world') # equivalent to foo.f(v, 'world')


I think this equivalence, being an answer to the subject sentence,
needs more emphasis. An instance method is a wrapped function and a
*class* attribute. The 'proper' way to call such functions,
consistent with all other function calls, is klass.meth(inst,
*rest_of_args), with inst as an explicit first arg matching the
explicit first parameter in the definition. To me, having an explicit
arg match an implicit param would be a warty inconsistency.

From this viewpoint, inst.meth(*rest_of_args) is a conveinient
abbreviation that works because of the attribute inheritance and
lookup mechanism. Of course, beyond being just syntactic sugar, it
adds the very important flexibility of the programmer not having to
know precisely which base class will provide the method. I think the
long form of method call should be taught first, and then the
abbreviation and behavioral reason for its existence. (Perhaps then,
we would have fewer threads on this topic ;-)

If an ad hoc 'self'-rule were added, the inconsistency would have to
be consistently applied to all function definitions. Python attaches
little special importance to the presence of a def within or without a
class suite.
Absent a metaclass override that affects function wrapping only for
those in the .__new__() dict arg but not when later assigned,

class k(object): # or no object
def f(self): pass

nicely abbreviates

def f(self): pass
class k(object): pass
k.f = f
del f

Terry J. Reedy


Jul 18 '05 #30

"Harri Pesonen" <fu****@sci.fi> wrote in message
news:Uc*****************@reader1.news.jippii.net.. .
I agree, it's not logical.
Do my previous two responses today make the logic any clearer?
I'm learning Python at the moment, and like it very much.


Try learning this. Class K method attribute f with params (s, *rest)
can be called as K.f(Kinst, *rest), consistent with all other function
calls.

Abbreviation Kinst.f(*rest) makes the call look inconsistent by making
K inplicit (and moving Kinst), but the same inplicitness enables
runtime method lookup and superclass inheritance. I think the
benefits that following are worth the minor bump in one's learning
curve.

Terry J. Reedy
Jul 18 '05 #31
Grant Edwards wrote:
In article <Uc*****************@reader1.news.jippii.net>, Harri Pesonen wrote:
I agree, it's not logical. I'm learning Python at the moment, and like
it very much. This "self" thing seems to be the only odd feature,


It seemed quite natural to me, but perhaps that's because I'd
used other languages that worked the same way. Coming from
Modula-3 and Smalltalk, the way classes worked in Python seemed
quite intuitive.

OTOH, C++ seems like a real non-intuitive mess to me.
it feels like the whole class feature was added later.


Why?


Because everything else in Python seems to be very compact, there are no
variable type declarations, or variable declarations, or anything else
unnecessary that can be omitted. I would like to have self omitted, it
would make the class syntax more beautiful and compact. On the other
hand, I would like to have real private methods.

Also I think that the class members should be explicitly declared. In
general, it would be nice to have an option (like Option Explicit in
Visual Basic) so that you can't assign to variables that have not been
declared. It would probably make Python less error prone. Also if
variable declarations could have the type, again some errors could be
detected at compile time.

I have not written any real Python applications yet, so I'm not expert,
these are just my thoughts at this point.

Harri

Jul 18 '05 #32
On Saturday 06 September 2003 02:17 pm, Terry Reedy wrote:
The main virtue of the inst.meth(*rest) abbreviation, with klass made
implicit, is not just to save typing the klass name but to push
determination of which 'klass' to the runtime inheritance tree,


Pardon me if this was mentioned previously, but another benefit is to simplify
the process of passing methods or stand-alone functions around - the user of
such functions doesn't have to differentiate between the two:

class Foo:
def OnEvent(self, a, b):
print 'Method', a, b

def Listener(a, b):
print 'Function', a,b

def SomeEventGenerator(eventListener):
eventListener(5, 6)

SomeEventGenerator doesn't care if the callback is actually a method or a
function. Both these work just fine:

f = Foo()
SomeEventGenerator(foo.OnEvent)
SomeEventGenerator(Listener)

Obviously, if the shorthand inst.meth(*rest) wasn't available there would
probably be another way to do the same thing, but "inst.meth" is concise and
does what you'd expect.

-Dave

Jul 18 '05 #33
On Sat, 6 Sep 2003 14:45:19 -0400, "John Roth" <ne********@jhrothjr.com> wrote:

"Bengt Richter" <bo**@oz.net> wrote in message
news:bj**********@216.39.172.122...
On Fri, 5 Sep 2003 20:15:00 -0400, "John Roth" <ne********@jhrothjr.com>

wrote:
>
>"Grant Edwards" <gr****@visi.com> wrote in message
>news:3f*********************@newsreader.visi.com. ..
>> In article <vl************@news.supernews.com>, John Roth wrote:
>>
>> >> So that there's no difference between a function and a method.
>> >>
>> >> Simplicity and orthogonality are good things -- despite what
>> >> C++ proponents thing.
>> >>
>> >> > Hence my comment that requiring it is more complex than not
>> >> > requiring it.
>> >>
>> >> No, it's more complex the Java/Ruby way, since you have to have
>> >> two sets of rules for what a name means depending on whether
>> >> you're inside a "normal" function or a method. In Python
>> >> there's just one set of rules -- mostly.
>> >
>> > As I said earlier, it's quite possible to define it so that there
>> > is always an instance of some kind; whether that's an instance
>> > a class or the module itself.
>>
>> I don't follow. You're talking about defining a keyword that
>> always refers to the first parameter passed to a function? And
>> the declared parameters would refer to the 2nd through Nth
>> parameters? What if the keyword isn't used in the function
>> definition, then do the delcared parameters refer to the 1st
>> through Nth?
>
>When Python invokes a function, it binds the operands in the
>function call to the identifiers named in the function / method
>header. If this is a method, it binds the instance (which is not
>in the invocation parameter list, btw.) to the first
>parameter in the method header.
>
>If you make "self" a reserved word, then all it has to do
>is bind the instance to "self," rather than the first identifier
>in the parameter list.
>
>In current python, there are two classes of functions (module
>level and embedded) and three classes of methods (instance,
>class and static.) Instance methods get the current instance,
>class methods get the class object as the instance, and the other
>three categories get nothing.
>
>As a separate suggestion, I'd have Python bind the module
>object to "self" for module functions and static methods. I
>haven't figured out what I want done with embedded methods
>and unbound methods yet. Notice that this eliminates the
>need for the global statement for module functions - all
>identifiers are accessible for rebinding through "self."
>
>> > I think my comments have shown that you can reduce the amount
>> > of scoping / name space rules noticably.
>>
>> Compared to what? It sure sounds like you're introducing more
>> rules than there are now. How would you propose reducing the
>> number of rules?
>
>If you don't have to write "self" as the first parameter of a method,
>that reduces the complexity. Everything else remains the same.


Will this still be possible?
>>> def foo(*args): print args

...
>>> class A(object): pass

...
>>> class B(A): pass

...
>>> a = A()
>>> b = B()
>>> A.bar = foo
>>> b.bar('howdy')

(<__main__.B object at 0x00906E70>, 'howdy')
>>> a.bar('howdy')

(<__main__.A object at 0x00907170>, 'howdy')
>>> foo('howdy')

('howdy',)
>>> A.bar('hello')

Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: unbound method foo() must be called with A instance as first

argument (got str instan
ce instead)
>>> A.__dict__['bar']('hello')

('hello',)

I.e., the method-vs-function distinction is a matter of how you access the

function dynamically,
not how you define it. There is no static distinction in functionality,

AFAIK (though I guess
there could possibly be some speculative optimizations).


It certainly needs to be. One of the reasons I haven't written a PEP is
that providing an instance to an unbound method is a case I don't have
a clear and simple answer to at the moment.

(The above doesn't even get into the multiple name issues I alluded to).

I don't think the multiple name issues are relevant - that has to do with
how the functions/methods are invoked, rather than what's in the header.)

I think we may be thinking of different things. Here is an admittedly artificial
example:
class A(object): ... def foo(a_self, *args):
... class B(object):
... def bar(b_self, *args):
... return 'This uses\na_self=%r and\nb_self=%r' % (a_self, b_self)
... return B
... a = A()
B = a.foo()
b = B()
print b.bar() This uses
a_self=<__main__.A object at 0x008F9BF0> and
b_self=<__main__.B object at 0x008F9FF0> b2 = B()
print b2.bar() This uses
a_self=<__main__.A object at 0x008F9BF0> and
b_self=<__main__.B object at 0x00903110>

If there were only one "self" keyword to use, you'd have to alias it explicitly
in the outer scope at least (a_self = self before the class B definition in the above).

Hm, I guess that part wouldn't be so bad, actually ;-)

Every function would be an unbound method with a potential undeclared local "self" binding,
and ordinary functions would of course not normally access "self", which would be a local
name error if it did so without a binding (though that brings up another issue: if functions
were to be instances of a function class -- how would you distinguish the function instance
"self" from object instance "self" if the function were playing the function role of a bound method?)

One problem would be breakage in code written with (*args) for parameters, expecting
args[0] to be "self" in bound method context.

For passing an instance to a function to make a bound method call, you wouldn't use
the fist slot in the parameter list, you'd have to use a mechanism like what is already
available, modified to bind to the implicit self instead of the first arg list parameter.
I.e., we now have:
def foo(x, y): print 'x=%r, y=%r, x*y=%r'%(x,y, x*y) ... foo(2,3) x=2, y=3, x*y=6 foo(2,'3') x=2, y='3', x*y='33'
bmeth = foo.__get__(2)
bmeth(7) x=2, y=7, x*y=14 bmeth('7') x=2, y='7', x*y='77'
foo.__get__(5)('X')

x=5, y='X', x*y='XXXXX'

So presumably foo.__get__(instance)(argx) would be the way to pass an instance to
an unbound method/function defined as, e.g., def foo(x): print 'self=%r, x=%r' % (self, x).

There'd be an awful lot of code to change though ;-/

Regards,
Bengt Richter
Jul 18 '05 #34
(Paul Foley replied to my e-mail directly. Below are his remarks,
which I was interested to read. At the end is my reply.)

1) I abhor redundancy. My first impression on seeing self as the first parameter of all method declarations is that it seems redundant -- it probably isn't technically, but it looks redundant: (self, (self,
(self, (self, ...
PF> Of course it's not redundant -- no more than the "x" is redundant
in

PF> def ln(x):
PF> ...

PF> def sin(x):
PF> ...

PF> def cos(x):
PF> ...

PF> def tan(x):
PF> ...

PF> def cosh(x):
PF> ...

PF> def sinh(x):
PF> ...

PF> etc., etc. Gee, look: (x, (x, (x, (x, (x, ...
2) The number of parameters in the method call is one less than the number of parameters in the method declaration.


PF> No it isn't. The first argument is just in a strange place:

PF> x.foo(y,z)
PF> ^ ^ ^
PF> 1 2 3

PF> x.foo is really just weird syntax for curry(foo, x); i.e.,

PF> q = x.foo

PF> is essentially

PF> q = lambda *a: foo(x, *a)

PF> (but in a different namespace), so

PF> x.foo(y,z) is q(y,z) is (lambda *a: foo(x, *a))(y,z)

PF> and there are exactly as many args in the call as in the
definition
PF> (as, of course, there must be!)
PF> Of course, it would be infinitely better to write foo(x,y,z),
opening
PF> the way to _real_ OO (with multiple dispatch), but x.foo(y,z) is
what
PF> Python supports...
I was interested to read your response.
I think you and I are looking through different lenses. Perhaps
influenced by my Java/Smalltalk background, I'm simply uncomfortable
when I see (1) the first parameter on all method declarations being
the object (didn't have to do this before) and (2) the number of
things
between the parentheses being different for the method declaration and
the method call.

On the other hand, when I read your response it's clear to me that (1)
you are comfortable looking through the lens of functional
programming, so that passing the object in as the first parameter
makes perfect sense to you, and (2) the mismatch in the number of
things
between the parentheses is not a big deal to you (though "strange",
you admit) because as an experienced Python programmer you know what's
going on under the covers.

My opinions are the frank opinions of a Java/Smalltalk programmer
learning Python. And I'm not the only newbie who thinks this seems
strange: the original newbie poster also opined that this is "odd".

Out of the mouths of babes ...
Jul 18 '05 #35

"Jonathan Aquino" <Jo********@shaw.ca> wrote in message
news:fc**************************@posting.google.c om...
, I'm simply uncomfortable when I see(2) the number of
things between the parentheses being different for the method
declaration and the method call.


If this bothers you enough, and you have a simple class without
inheritance, you *can* write the call in its full form
'class.meth(inst, a, b, ...)' so that you *do* have the same number of
things in declaration and call. Then revert to the shorter form when
comfortable. I am beginning to think methods calls should be taught
this way.

Terry J. Reedy
Jul 18 '05 #36
Terry Reedy wrote:
"Jonathan Aquino" <Jo********@shaw.ca> wrote in message
news:fc**************************@posting.google.c om...
, I'm simply uncomfortable when I see(2) the number of
things between the parentheses being different for the method
declaration and the method call.


If this bothers you enough, and you have a simple class without
inheritance, you *can* write the call in its full form
'class.meth(inst, a, b, ...)' so that you *do* have the same number of
things in declaration and call. Then revert to the shorter form when
comfortable. I am beginning to think methods calls should be taught
this way.


The constraint of "a simple class without inheritance" is too strong.

As long as you know the class of inst, theclass.meth(inst, a, b) will
work no matter how complicated theclass is or how many other
classes it inherits from. The problem is rather one of a loss of
polymorphism when you DON'T know the class of inst. THAT one
you can overcome with type(inst).meth(inst, a, b) [except where
inst is an instance of an _old-style_ class] -- now, this only leaves
you the problem of inst having a _per-instance_ override of name
'meth'... in that peculiar case, inst.meth would pick it up but
type(inst).meth wouldn't.
Alex

Jul 18 '05 #37
On Thu, 11 Sep 2003 11:33:38 +0000 (UTC), Grzegorz Staniak <gs******@inka.zagiel.pl> wrote:
[...]
To sum up what I've learnt here and from the FAQ: 'self' could actually be
any string (it is 'self' by convention), as its role is only to serve as
the first argument of methods in order to facilitate the process of
associating method calls with their context. It would be possible (even if
not obviously desirable) to implement method definitions in such a way
as to avoid the first argument completely, i.e.

def something():
...

so actually it's just a question of implementation. Having little
experience with object-oriented programming, I won't try to relate to
pro and contra arguments that have been given in the discussion, I just
have one more question: isn't it a little superfulous to have to use the
'classmethod()' builtin to declare class methods? I'd think giving a
class object name as the first argument should suffice?

I think you may have misunderstood classmethod. Rebinding a class attribute
with the result of classmethod makes a method that
works differently from an ordinary method. It means that the class itself will
be bound to the first argument, even if the method is called as an attribute
of an instance of the class. E.g.,
class A(object): ... def cm(*args): return args
... cm = classmethod(cm)
... def m(*args): return args
... class B(A): pass ... a= A()
b= B()
a.cm() (<class '__main__.A'>,) a.m() (<__main__.A object at 0x00902350>,) b.cm() (<class '__main__.B'>,) b.m() (<__main__.B object at 0x008F9690>,)

and note:
A.cm() (<class '__main__.A'>,) B.cm() (<class '__main__.B'>,)

but: A.m() Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: unbound method m() must be called with A instance as first argument (got nothing instead) B.m() Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: unbound method m() must be called with B instance as first argument (got nothing instead)

also, you don't have to do it inside the class definition, and it's not about a specific
attribute name -- i.e. you don't have to write xxx = classmethod(xxx) as is conventional,
unless the following is fooling me.
def bar(*args): return 'bar %r'%args ... class C(B): pass ... C.cmbar = classmethod(bar)
c=C()
c.cmbar() "bar <class '__main__.C'>" C.cmbar() "bar <class '__main__.C'>" c.cm() (<class '__main__.C'>,) c.m() (<__main__.C object at 0x00902170>,)

Of course the result is not *identical*, since you can see the original function name
(note that you get a *bound* method either way with a classmethod, vs the ordinary C.m/c.m)
C.cmbar <bound method type.bar of <class '__main__.C'>> c.cmbar <bound method type.bar of <class '__main__.C'>> C.cm <bound method type.cm of <class '__main__.C'>> c.cm <bound method type.cm of <class '__main__.C'>> C.m <unbound method C.m> c.m

<bound method C.m of <__main__.C object at 0x00902170>>

Regards,
Bengt Richter
Jul 18 '05 #38

This discussion thread is closed

Replies have been disabled for this discussion.

By using this site, you agree to our Privacy Policy and Terms of Use.