The story of the explicit self in method definitions has been
discussed to death and we all know it will stay. However, Guido
himself acknowledged that an alternative syntax makes perfect sense
and having both (old and new) in a future version of python is a
possibility since it maintains backward compatibility. The alternative
syntax will be syntactic sugar for the old one. This blog post of his
is what I'm talking about:
http://neopythonic.blogspot.com/2008/10/why-explicit-self-has-to-stay.html
The proposal is to allow this:
class C:
def self.method( arg ):
self.value = arg
return self.value
instead of this:
class C:
def method( self, arg ):
self.value = arg
return self.value
I.e. explicit self stays only the syntax is slightly different and may
seem attractive to some. As pointed out by Guido classmethods would
work similarly:
class C:
@classmethod
def cls.method( arg ):
cls.val = arg
return cls.val
The fact that Guido says,
"Now, I'm not saying that I like this better than the status quo. But
I like it a lot better than [...] but it has the great advantage that
it is backward compatible, and can be evolved into a PEP with a
reference implementation without too much effort."
shows that the proposal is viable.
I'd like this new way of defining methods, what do you guys think?
Anyone ready for writing a PEP?
Cheers,
Daniel
--
Psss, psss, put it down! - http://www.cafepress.com/putitdown
> I'd like this new way of defining methods, what do you guys think?
Consider the maverick who insists on
class C:
def me.method(arg):
self.value = arg
which should be equivalent to
class C:
def method(me, arg):
me.value = arg
What's the interpreter going to do with our maverick's code?
James
class C:
def me.method(arg):
me.value = arg
James
> Daniel Fetchinson wrote:
>> http://neopythonic.blogspot.com/2008/10/why-explicit-self-has-to-
stay.html
>>
>> The proposal is to allow this:
>>
>> class C:
>> def self.method( arg ):
>> self.value = arg
>> return self.value
>>
>> instead of this:
>>
>> class C:
>> def method( self, arg ):
>> self.value = arg
>> return self.value
>
>> I'd like this new way of defining methods, what do you guys think?
>
> Consider the maverick who insists on
>
> class C:
> def me.method(arg):
> self.value = arg
Replace "self" with "me".
> which should be equivalent to
>
> class C:
> def method(me, arg):
> me.value = arg
>
> What's the interpreter going to do with our maverick's code?
I don't see why you think this is a problem. The compiler merely treats:
def ANYTHING.method(arg):
inside a class as if it were
def method(ANYTHING, arg):
and it will Just Work. If you want a classmethod, you still need to use
the classmethod decorator -- there's no reason to make self and cls
keywords.
Personally, I'm neutral on the idea. Perhaps +0.00001.
--
Steven
I don't really like the proposed syntax any better than the old
syntax. I certainly wouldn't use "def self." in any of my old code.
I doubt I would use it in a new project were I to have the choice
either. However, I don't really have a problem with other people
liking it.
the symetry of "def self.func(blah)==def func(self,blah)" and
"ob.func(blah)==func(ob.blah)" is kind of neat.
Could I do something like this:
def a.add(b): return a+b
Outside of a class? Of course then that makes you think you could do
5.add(6) or something craaaazy like that. (I mean, you can do
(5).__add__(6) but that's something else entirely)
So both forms are dual to each other ( "backwards compatibility" ) and
can be used both?
I'm -0 on this although I think the proposition fits better with the
method call syntax.
I like it.
I'll even go a step further and suggest that "$" be allowed as a
substitute for "self". It looks like a capital "S" (for Self), and it
stands out clearly. It also makes code more succinct with no loss of
readability. Think of the line wraps that could be avoided.
>> Daniel Fetchinson wrote:
>>> I'd like this new way of defining methods, what do you guys think?
>> Consider the maverick who insists on
>>
>> class C:
>> def me.method(arg):
>> self.value = arg
>
> Replace "self" with "me".
Yes, I corrected myself one minute after I made the typo.
>> which should be equivalent to
>>
>> class C:
>> def method(me, arg):
>> me.value = arg
>>
>> What's the interpreter going to do with our maverick's code?
>
> I don't see why you think this is a problem.
The behavior was unspecified as far as I could tell and I was curious as
to whether "me" would still be allowed as a reference to self. Allowing
alternatives to "self" would maintain backwards compatibility as the use
of self has been a convention and not enforced by the language.
James
--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095
>>> import this
and look at the 15th line...
I agree that for newcomers to Python, the class method definition might
seem strange. I certainly had problems with it when starting with
Python, coming from Java. But in the meantime it feels right. I don't
know if it is because I'm used to the old way, but I find the proposed
alternative way slightly less readable.
Altough these are no technical considerations, I'm -1 on this.
class C:
def method($, arg):
$.value = arg
I'm strongly against this. This looks ugly and reminds me of Perl and
Ruby. (I don't have anything against these languages, but there's a
reason I use Python).
> try this:
>
>>>> import this
>
> and look at the 15th line...
The reason why I'm against that change too. It adds a second,
alternative way to express something that is already in the language.
> I agree that for newcomers to Python, the class method definition might
> seem strange.
And after the change it continues to because they will run into *both*
variants in tutorials, code, and books, so it might be even more
confusing.
Ciao,
Marc 'BlackJack' Rintsch
> On Sat, 06 Dec 2008 09:56:12 +0100, Antoine De Groote wrote:
>
> [snip reference to "preferably only one way to do it"]
>
> The reason why I'm against that change too. It adds a second,
> alternative way to express something that is already in the language.
>
> > I agree that for newcomers to Python, the class method definition
> > might seem strange.
>
> And after the change it continues to because they will run into
> *both* variants in tutorials, code, and books, so it might be even
> more confusing.
>
I agree with that view. Not much to add to it, just increasing the
weight.
/W
--
My real email address is constructed by swapping the domain with the
recipient (local part).
I think this (that is just sugar) may be a little better:
class C:
def method($, arg):
$value = arg
Or even this, combined with the idea suggested in the post by Guido:
class C:
def $method(arg):
$value = arg
(Note there's no point after $, it's not currently possible).
Ruby uses @ and @@ for similar purposes.
I agree that the code looks worse, but also shorter to read and write,
so in lines of code that use many instance attributes, that short $
syntax helps keep the line shorter. So I may grow to accept this
sugar...
Bye,
bearophile
Would it be valid outside class definitions too? (As follows...)
def sequence.shuffle( ):
x= sequence[ 0 ]
sequence[ 0 ]= sequence[ -1 ]
...etc.
shuffle( listA )
Can you still call it by class membership? (As follows...)
C.method( inst, arg )
> class C:
> def $method(arg):
> $value = arg
>
> (Note there's no point after $, it's not currently possible).
> Ruby uses @ and @@ for similar purposes.
> I agree that the code looks worse, but also shorter to read and write,
> so in lines of code that use many instance attributes, that short $
> syntax helps keep the line shorter. So I may grow to accept this
> sugar...
>
But that is not the way Python is meant to work. There are several
tennets in the Zen of Python that don't chime well with this approach.
"self" is a speaking identifier, "$" isn't.
we've-been-through-this-ingly yours
> On Sat, 6 Dec 2008 04:02:54 -0800 (PST) bearoph...@lycos.com
> suggested:
>
>
> > class C:
> > def $method(arg):
> > $value = arg
> >
> > [snip]
> >
> [snip]
> "self" is a speaking identifier, "$" isn't.
>
Also, nothing prevents you from replacing "self" with "s" if you really
want it short. Same effect as your "s" suggestion (OK, plus one ".").
bearoph...@lycos.com wrote:
> Antoine De Groote:
>> Allowing "$" as a substitute for "self" wouldn't require this new syntax.
>> class C:
>> def method($, arg):
>> $.value = arg
>
> I think this (that is just sugar) may be a little better:
>
> class C:
> def method($, arg):
> $value = arg
Well, in this case there would be no need to have the $ in the arguments
list, as it would be like a "keyword", or a keysymbol in this case, like
the "this" keyword in Java for instance.
I dislike this even more than the dotted version.
This is not what was intended. The discussion was explicitly only about
class methods.
What you are describing is weird and not generalizable. What if your
method takes more than one parameter? You might argue that "sequence"
would be the first argument in the list, like
def sequence.shuffle(a, b):
"""
a, b: dummy arguments, just for the sake of the example
"""
x = sequence[0]
sequence[0] = sequence[-1
...etc.
shuffle(listA, 1, 1)
I can't think of any good reason to do this. What's more, the whole
discussion was partly due to error messages like
Traceback (most recent call last):
File "classes.py", line 9, in
obj.m2(1)
TypeError: m2() takes exactly 3 arguments (2 given)
Your proposition (well actually it is only a question) would result in
error messages exactly like this one when one would not carefully read
the method signature for example.
>
> Can you still call it by class membership? (As follows...)
>
> C.method( inst, arg )
That should not change at all, as the alternative syntax would actually
be only syntactic sugar.
> Consider the maverick who insists on
8<--------example with "me" instead of "self" --------
> What's the interpreter going to do with our maverick's code?
Took me a while, but after I remembered that a "maverick"
is an unmarked, wild member of the bovine species that
is effectively res nullius, I suppose the answer should be that
he or she be brought back into the fold by being branded in
the normal fashion - the application of a hot iron, in the shape
of the standard python logo, to the buttocks.
- Hendrik
The quoted blogspot is not available.
I like the idea but I don't see how
explicit and implicit can co-exist.
Version 3.0 is the time to introduce the
enhancement.
Colin W.
The quoted blogspot is not available.
Sigh. If you make --both-- self and cls keywords, then 90% of the
problems that Guido mentions in the blogspot post just vanish because
whether it's an instance method, a class method or a static method can
be inferred from the method body.
In particular, the decorator problem goes away (the decorators are
irrelevant, and can be ignored) and so does the problem with injecting
a method into an object.
It is, of course, harder to implement, and it would not be backwards
compatible because all the internal wrappers vanish as well. That
makes problems for anyone who is looking through __dict__ to find
particular kinds of method.
John Roth
It looks "ugly" simply because it is new to you. Once you get used to
it, I'll bet it will look fine. And resemblance to another language is
not a very good reason to reject it.
Is "@" a "speaking identifier? How about "#" and "!="? Last I heard,
they were all part of Python.
Yes, you can always use "s". But single-letter identifiers are not
usually a good idea, because they are hard to search on. A slightly
better option is "S", which is a little better for searching but not
as good as "$". I have considered using "S" extensively in my code,
but I hesitate because it is not recognized in official Python coding
standards.
> On Dec 6, 4:32 am, Andreas Waldenburger <geekm...@usenot.de> wrote:
>> On Sat, 6 Dec 2008 04:02:54 -0800 (PST) bearophileH...@lycos.com wrote:
>>
>> > class C:
>> > def $method(arg):
>> > $value = arg
>>
>> > (Note there's no point after $, it's not currently possible).
If -- and that's a HUGE if -- the compiler is changed to allow $method,
it could certainly be changed to allow $.method.
>> > Ruby
>> > uses @ and @@ for similar purposes. I agree that the code looks
>> > worse, but also shorter to read and write, so in lines of code that
>> > use many instance attributes, that short $ syntax helps keep the line
>> > shorter. So I may grow to accept this sugar...
If a line of code uses too many instance attributes to fit comfortably on
a line, spread it over two lines. There is no newline shortage, they are
a renewable resource.
>> But that is not the way Python is meant to work. There are several
>> tennets in the Zen of Python that don't chime well with this approach.
>> "self" is a speaking identifier, "$" isn't.
>
> Is "@" a "speaking identifier? How about "#" and "!="? Last I heard,
> they were all part of Python.
Yes they are.
@f
is pronounced "at f" or "decorate f".
# comment
is pronounced "hash comment" or even not pronounced at all.
x != y
is pronounced "x not equal to y"
The proposed
def $method(arg):
would be pronounced "def dollar method arg" or "def method self arg". The
first is ugly to my ears, the second confusing.
-2 on this proposal.
--
Steven
-1
As far as I'm concerned, it doesn't add anything to the language, nor
doesn't save any typing, so I just don't see the point. And having it
co-existing with the normal syntax will only add more confusion.
NB : FWIW, I would eventually have voted -0 if it had been proposed for
Python 3, and as a _replacement_ (not _alternative_) to the current
syntax. But Python 3 is now released, so...
I would not say that "ugly" and "new" (or "unused" for that matter) are
the same. There are going to be a number of things in Python 3 that are
new and to which one is not used, but they certainly are not ugly. Ugly
is of course a matter of taste, I'll give you that, but to me it's still
ugly.
Regarding "$" as a stand-in for "self" is less of a stretch than the
examples you gave.
> -2 on this proposal.
Did you get two votes in the Presidential election too? 8^)
Splitting lines is generally possible, but sometimes it's not I want,
for example to keep a formula whole.
And splitting lines increases line count. Increasing line count may
reduce the amount of code you can see in a screenshot, and this may
decrease a little the programmer's ability to understand code.
(I am not suggesting to cram everything into one or few lines, like in
K language: regarding code size there's an optimal middle point
between K/APL and Ada/certain Java. Still, typing "self." very often
requires time, and even if you are lucky to have an IDE that helps you
write that faster, the code uses lot of space anyway).
That's why I say that the following code, while looking a little ugly,
may be a little "better" anyway (and maybe even more readable):
class ThisIsAClass:
def $some_method(arg1, arg2):
$value = arg1 + $foo + $bar + $baz * arg2
...
Than the current syntax:
class ThisIsAClass:
def some_method(self, arg1, arg2):
self.value = arg1 + self.foo + self.bar + self.baz * arg2
...
Bye,
bearophile
I think my biggest problem with this is what got me off Perl.
Add $, together with already used @ and maybe some other
identifiers and I start loosing track of what each of the character
means. It is fine when you are used to the language, but
learning it becomes a harder proposition. self.foo is self-explanatory
(no pun intended) to me, $foo is not.
Cheers
Tommy
Hmm,
I'd give the proposal a -1. Perhaps I'm missing something though.
Does this really justify an enhancement?
Whether the implicit parameter is prepended with a dot or whether it's
the first parameter with the parantheses doesn't save me any typing and
the benefit of 'visualizing' how the function should be called seems
minor to me.
What would be interesting would be some syntactical sugar to get rid of
the 'self' (at least in the code body).
example:
class C:
class_elements a,b,c,d
def method(self,arg):
global d
a,b,c = arg[0..3]
d = a + b
self.e = a + d
instead of
class C:
def method(self,arg):
self.a,self.b,self.c,self.d = arg[0..4]
self.e = self.a + self.b
As far as I understood (I never really followed any of these threads),
getting rid of self has already been discussed and rejected many times.
bye
N
> Hi folks,
>
> The story of the explicit self in method definitions has been
> discussed to death and we all know it will stay. However, Guido
> himself acknowledged that an alternative syntax makes perfect sense
> and having both (old and new) in a future version of python is a
> possibility since it maintains backward compatibility. The alternative
> syntax will be syntactic sugar for the old one. This blog post of his
> is what I'm talking about:
>
> http://neopythonic.blogspot.com/2008/10/why-explicit-self-has-to-stay.html
>
> The proposal is to allow this:
>
> class C:
> def self.method( arg ):
> self.value = arg
> return self.value
>
> instead of this:
>
> class C:
> def method( self, arg ):
> self.value = arg
> return self.value
>
> I.e. explicit self stays only the syntax is slightly different and may
> seem attractive to some. As pointed out by Guido classmethods would
> work similarly:
>
> class C:
> @classmethod
> def cls.method( arg ):
> cls.val = arg
> return cls.val
>
> The fact that Guido says,
>
> "Now, I'm not saying that I like this better than the status quo. But
> I like it a lot better than [...] but it has the great advantage that
> it is backward compatible, and can be evolved into a PEP with a
> reference implementation without too much effort."
>
> shows that the proposal is viable.
>
> I'd like this new way of defining methods, what do you guys think?
> Anyone ready for writing a PEP?
>
What's the advantage? If there is not a good reason, I would strongly opposed polluting the language.
I'd be inclined to think that this defines an instancemethod on an
existing object a. In other word, I'd read the following two lines as
more or less equivalent.
def a.add(b): return a+b
a.add = lambda b: a+b
Just as the following are equivalent:
def foo(): return bar
foo = lambda: bar
I had been -0 on this, but now I think I'm -1.
Carl Banks
None of them are identifiers. $, used as proposed, would be.
(Then again, _ is an identifier.)
Carl Banks
Perl is not new to me and I am familiar with the syntax, such as it
is. I find it unspeakably ugly. So, no, you would lose your bet if
it were me.
Carl Banks
-1
I explained why deep in the thread but I'll elaborate more here. When
I see a def statement, I mentally equate that to an assigment to the
thing being def'ed. So for instance, when I see this:
def <something>():
I think of it like this:
<somthing> = <the defined function>
Thus, if I were to see a function definition like this
def foo.bar(): return 1
I would think you were defining a function and assigning it to
foo.bar. IOW, it would be mostly equivalent to this:
foo.bar = lambda: 1
(Analogously, I would expect a definition like this:
def baz[10](): return 1
to be equivalent to this:
baz[10] = lambda: 1 )
So, if, inside a class definition, I were to see this:
def self.method(): return 1
Well, I'd understand that is was a method assigment, of course, but it
would conflict with what I would expect the natural meaning of
something like def a.b() would be. The above statement is not
equivalent to:
self.method = lambda: 1
but I think that's what it ought to be, in general.
Carl Banks
It doesn't add anything but makes something that exists a bit clearer
and friendlier to newbies. Saving typing was never the intention.
> NB : FWIW, I would eventually have voted -0 if it had been proposed for
> Python 3, and as a _replacement_ (not _alternative_) to the current
> syntax. But Python 3 is now released, so...
There will be python 4000 eventually :)
Maybe only this alternative syntax for python 4000?
Did you read the blog post? The advantage is having a less confusing
situation for newbies (confusing the number of arguments to a method
call).
>
> --
> http://mail.python.org/mailman/listinfo/python-list
Similarly, to those coming from Ruby or those operating under the
frequent misunderstanding that the `def`s are happening in the context
of a class object (which in reality has yet to be created), `self` in
this context might be misconstrued as the class object and thus `def
self.foo` might be misunderstood (through the intuitive equivalence
you mention) as a defining a classmethod rather than an instance
method.
I also strongly echo the TOOWTDI arguments against adding this
duplicative syntax. It's a minor gain but costs much more than it's
worth for violating The Zen.
Cheers,
Chris
--
Follow the path of the Iguana...
http://rebertia.com
>
>
>
> Carl Banks
>
>
> --
> http://mail.python.org/mailman/listinfo/python-list
>
I don't know much about Perl, but my understanding is that a dollar
sign must be used every time a variable is dereferenced, as in bash or
other shell languages. What we are proposing here is something
entirely different: the dollar sign would simply be a shorthand for
"self". In Perl, the dollar sign is clutter, but in this case it
actually reduces clutter.
Python already uses shorthand extensively. How about "def"? For people
who are so worried about self-explanatory symbols, what the heck does
that stand for? Default? Defeat? Defect? Defunct? Defer?
At some time in the past, a conscious decision was made to save three
characters in the word "define" by abbreviating it as "def". The
suggestion to abbreviate "self" as "$" also saves three characters.
And "self" appears much more often than "def", so an abbreviation is
equally or more justified in my opinion.
> I don't know much about Perl, but my understanding is that a dollar
> sign must be used every time a variable is dereferenced, as in bash or
> other shell languages. What we are proposing here is something
> entirely different: the dollar sign would simply be a shorthand for
> "self". In Perl, the dollar sign is clutter, but in this case it
> actually reduces clutter.
>
This is the weirdest thing. Not a month seems to go by that this old
hat isn't dug up again. You're fighting windmills. Why do you think
self has been around so long? Because it's the best choice? No, because
it works and there just is no need to change it (where "need" is
defined by the desires of the majority).
Getting the Python comunity to replace self with something shorter will
never compensate for the time you spent bullying it through. I'd much
rather spend time coding than complaining, but that might be just me.
(BTW: I have my editor set up so that "s" is expanded to "self" and "."
is expanded to "self."; I virtually lose no time at all with self and
would gain nothing from a change to it.
And regarding line-lengths: My code lines tend to be shorter than my
comments explaining them, but that may again be just me.
Excuse my being stubborn. :)
/W
--
My real email address is constructed by swapping the domain with the
recipient (local part).
>> -2 on this proposal.
>
> Did you get two votes in the Presidential election too? 8^)
You know, occasionally you stumble across people on the Internet who
aren't from the USA. Some of us even speak English almost as good as
native speakers *wink*
In any case, in this context -2 refers to the strength of feeling, not
the number of votes. Python is not a democracy, and our Beloved BDFL
Guido graciously takes our needs and wants into account before making
decisions.
--
Steven
But it's ugly. No amount of rationalization will make it not ugly.
> Python already uses shorthand extensively. How about "def"? For people
> who are so worried about self-explanatory symbols, what the heck does
> that stand for? Default? Defeat? Defect? Defunct? Defer?
>
> At some time in the past, a conscious decision was made to save three
> characters in the word "define" by abbreviating it as "def". The
> suggestion to abbreviate "self" as "$" also saves three characters.
> And "self" appears much more often than "def", so an abbreviation is
> equally or more justified in my opinion.
def isn't ugly.
Carl Banks
> Python already uses shorthand extensively. How about "def"? For people
> who are so worried about self-explanatory symbols, what the heck does
> that stand for? Default? Defeat? Defect? Defunct? Defer?
That's pretty silly; it's pretty obvious that `def` means "define," and
even if that weren't obvious on its face, in context it's _really_
obvious. `def f(): ...` certainly isn't going to be confused to a
request to defecate on something called `f`, after all -- which is about
as plausible as your other suggestions.
`$` as a shortcut for self, on the other hand, gives absolutely no
mnemonic indication what it stands for, and users would be simply left
guessing.
P.S. You're beating a long-dead horse here; your precise proposal has
been brought up countless times on comp.lang.python and shot down every
single time for the same reason. It isn't going to happen.
--
Erik Max Francis && m...@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 18 N 121 57 W && AIM, Y!M erikmaxfrancis
There are not fifty ways of fighting, there is only one: to be the
conqueror. -- Andrew Malraux, 1937
None of these are identifiers at all. You might want to read up on the
language reference to see what an identifier actually is.
The dollar sign is ugly? I beg to differ.
> Did you read the blog post? The advantage is having a less confusing
> situation for newbies (confusing the number of arguments to a method
> call).
Experience suggests that newbies don't find this confusing, or at
least not more than momentarily.
I'm -0 on this at the moment. Maybe -0.5. I don't really like the
potential for hideousness like
@staticmethod
def spam.alot(isa, silly, place):
return silly + spam
that's implied by making this a general feature of methods.
--
Rhodri James *-* Wildebeeste Herder to the Masses
And something tells me that it will keep coming up many more times in
the following years too.
Bye,
bearophile
Nope, you're wrong.
Carl Banks
(See where this is going?)
Me too. And it smells like Perl if we let the $ get in there. And it doesn't
add any facility to the language - it's just syntactic lint.
So -1 from me.
--
Cameron Simpson <c...@zip.com.au> DoD#743
http://www.cskk.ezoshosting.com/cs/
Nah, that would make it not explicit. Explicit here also means that to
refer to self's a, we need to explicitly refer to self.
To sum up:
Arguments on Status Quo:
+ Andreas Waldenburger: it works and there just is no need to change
it
+ need no change
+ Andreas Waldenburger: Getting the Python comunity to replace self
with something shorter will never compensate for the time you spent
bullying it through
- Confusion for number of parameters
- The standard 'self' is too long
- Newbie FAQ
- It is ugly
Arguments on "def self.method(" as "def method(self" inside a class:
+ OP: It reduces confusion for number of parameters
+ Patrick Mullen: The symetry of "def self.func(blah)==def func
(self,blah)" and "ob.func(blah)==func(ob.blah)" is kind of neat.
+ OP: Backward compatible
+ OP: It is explicit
- Marc 'Blackjack' Rintsch: they [newcomers] will run into *both*
variants in tutorials, code, and books, so it might be even more
confusing.
- Carl Banks: def <something>(): == <somthing> = <the defined
function>, but def self.method(): return 1 != self.method = lambda: 1
- `self` in this context might be misconstrued as the class object and
thus `def self.foo` might be misunderstood ... as a defining a
classmethod rather than an instance method.
- It is ugly
? Syntax sugar or replacement? Many people prefers this to be
replacement to reduce confusion.
Arguments on variants of $
+ Russ P.: looks like S(elf)
+ Russ P.: more succinct with no loss of readability
- Antoine de Groote: slightly less readable.
- Antoine de Groote: wouldn't require this new syntax (def meth($,
args): $.foo)
- Andreas Waldenburger: "self" is a speaking identifier, "$" isn't
- Obscure symbol
- It is ugly
Unresolved:
? Patrick Mullen: Outside a class definition?
I think we have to test this on newbies. Personally, I think the new
syntax would confuse newbies too, though not as much as the tricky
error message we currently have (code: foo.bar(1, 2, 3, 4); Error:
TypeError: foo() takes exactly 4 arguments (5 given); Newbie: "what
the... 1.. 2.. 3.. 4.., I correctly gave 4 arguments, python counted
the wrong number of arguments").
If this dead horse is revived because of that reason, then I'd go with
changing the error message to something that is less confusing to
newbies[1]. I remember being tripped with the (thinking that python
miscounted the number of argument) when I was new. This has the
advantage of backward compatibility and no syntax change, just less
misleading error message.
[1] anything could work, but I like this one: (c is an instance of
class C)
if the code is: c.foo(...), Error: "TypeError: c.foo() takes exactly 3
argument"
while if the code is: C.foo(...), Error: "C.foo() takes exactly 4
arguments"
You can implement c.foo as a curried C.foo function, catch C.foo's
TypeError exception then reraise it as c.foo exception.
I think the difference here is that those other abbreviations are
mostly fairly standard. The "def" keyword is the same in Ruby, and
similar enough to "define" or "defun" in Scheme or LISP. The "!="
operator is pretty much standard across nearly all languages. What is
being proposed with "$" here though, would be different from how it is
used anywhere else and would be confusing.
Moreover, I especially don't like proposing to eliminate as well in this
instance the "dot notation", which is standard in nearly all object
oriented languages. Using something as a substitute for "self" is one
thing, and you can mostly use what you like there now, as "self" is more
a convention than a requirement. But the "dot" that belongs there is
critical to understanding, you can't hide that to save one keystroke.
Getting back to Guido's suggestion, though, I think it makes some sense.
Being new to Python, I did find myself occasionally forgetting "self" in
instance methods. But, I also thought the requirement to include it was
helpful in reminding me what was really going on there, that I was
creating an instance method which was really a function that wouldn't
actually be created until the instance was initiated. I tend to think
this may be clearer though using the dot notation rather than passing
the instance variable as a parameter.
I'm not sure though whether allowing both syntaxes would make things
more or less confusing. It might actually be helpful in some respects
for newcomers to realize that self.method(arg) is somewhat the same as
method(self, arg). Perhaps I'm wrong on this, I don't fully understand
yet what is going on under the hood, but it seems to me that that would
be part of the glue that allows Python to be so multi-paradigm; much of
the difference between OOP and procedural or functional is just
different syntax for the same thing.
I don't understand your answer.
I'm not very knowledgable with all the OO vocabulary, but just use OO.
self.a , self.b , self.c are stored in the object and could later be
used by other object-methods.
like
def print_a_b_c(self):
print self,a,self.b,self.c
the name 'class_elements' was just a suggestion it could be also
something like 'auto_prepend_self' or whatever.
bye
N
Dennis Lee Bieber wrote:
> On Sat, 06 Dec 2008 19:02:22 +0100, News123 <new...@free.fr> declaimed
> the following in comp.lang.python:
>
>
>> example:
>> class C:
>> class_elements a,b,c,d
>>
>> def method(self,arg):
>> global d
>> a,b,c = arg[0..3]
>> d = a + b
>> self.e = a + d
>>
>> instead of
>> class C:
>> def method(self,arg):
>> self.a,self.b,self.c,self.d = arg[0..4]
>> self.e = self.a + self.b
>>
> I would declare this a poor example, since a, b, c, aren't used as
> attributes -- they are just invocation locals.
Well being explicit when trying to suggest an implicit syntax (in order
to reduce typing) is a little difficult ;-)
Though you're right my main goal is not being implicit but would be
reducing typing and have shorter source code lines.
If 'global '<varname>' is accepted inside a def, then moving
'class_elements <varnames>' inside the def could be acceptable as well
though it would requiere, that this statement is repeated per def
bye
N
> Sorry Dennis,
>
>
> I don't understand your answer.
> I'm not very knowledgable with all the OO vocabulary, but just use OO.
>
> self.a , self.b , self.c are stored in the object and could later be
> used by other object-methods.
In Python terminology, they are called "attributes". This is fairly
standard for most OO languages too.
If the attribute is stored in the instance, it is an "instance
attribute". If it is shared by all instances and stored in the class, it
is a "class attribute".
--
Steven
[about removing self]
> P.S. You're beating a long-dead horse here; your precise proposal has
> been brought up countless times on comp.lang.python and shot down
> every single time for the same reason. It isn't going to happen.
I guess it's part of the process of learning Python :)
--
Arnaud
> I'm not sure though whether allowing both syntaxes would make things
> more or less confusing. It might actually be helpful in some respects
> for newcomers to realize that self.method(arg) is somewhat the same
> as method(self, arg). [snip]
A professor of mine once said something to the effect that in teaching
it is not so important to *tell* people a lot but to *omit* as much as
practically possible. This might be the single most wise thing I have
ever heard.
If you're a newbee and you know nothing of the language, and probably
nothing about programming at all, having two possibilities will
thoroughly confuse you. Only when you have a working(!) knowledge of
one version will you be able to appreciate the other. Since in this
case the other option has no practical benefits whatsoever (IMHO),
there's absolutely no need for it.
/W
PS: I will state again that I do like the idea in itself, its just about
20 years too late for it.
> I think we have to test this on newbies. [snip]
>
Now that's talking like a programmer!
Ideas on how such a survey could be conducted? Anyone?
> If this dead horse is revived because of that reason, then I'd go with
> changing the error message to something that is less confusing to
> newbies[1].
+ googol
> I remember being tripped with the (thinking that python
> miscounted the number of argument) when I was new. This has the
> advantage of backward compatibility and no syntax change, just less
> misleading error message.
>
> [1] anything could work, but I like this one: (c is an instance of
> class C)
> if the code is: c.foo(...), Error: "TypeError: c.foo() takes exactly 3
> argument"
> while if the code is: C.foo(...), Error: "C.foo() takes exactly 4
> arguments"
> You can implement c.foo as a curried C.foo function, catch C.foo's
> TypeError exception then reraise it as c.foo exception.
I'm not sure that I'd find that less confusing. Because a c.foo()
*does* take four arguments, not three. It's just that the first one is
implicit (Right?).
How about:
"TypeError: c.foo() takes exactly 3 arguments in addition to
the implicit instance reference."
or
"TypeError: c.foo() takes exactly 4 arguments (5 given, including the
implicit instance reference)"
... or something less kludgy in that general direction. This would
explain exactly what is wrong.
/W
This is actually a real counter argument, I think. Self, the instance,
doesn't exist until it is created and certainly doesn't exist during
class creation. So something like
class C:
def self.meth( arg ):
return arg
can be confusing since 'self' appears as if it was defined in the
scope of C but clearly it isn't yet.
Err... I fail to see how magically transforming def self.foo(...) into
def foo(self, ...) makes anything clearer about what really happens and
how Python's object model works.
> and friendlier to newbies.
I'd rather say "more acceptable to java-brainwashed developpers".
> > and friendlier to newbies.
>
> I'd rather say "more acceptable to java-brainwashed developpers".
Why would you rather be unfriendly and seed ambivalence? I do see the
fun in a little Python snobbism, but ... come on.
This has been debated to hell and back. And it's *not* going to happen.
>>> example:
>>> class C:
>>> class_elements a,b,c,d
>>>
>>> def method(self,arg):
>>> global d
>>> a,b,c = arg[0..3]
>>> d = a + b
>>> self.e = a + d
>>>
>> Nah, that would make it not explicit. Explicit here also means that to
>> refer to self's a, we need to explicitly refer to self.
>
> Well being explicit when trying to suggest an implicit syntax (in order
> to reduce typing) is a little difficult ;-)
>
> Though you're right my main goal is not being implicit but would be
> reducing typing and have shorter source code lines.
then use 's' instead of 'self'.
> If 'global '<varname>' is accepted inside a def, then moving
> 'class_elements <varnames>' inside the def could be acceptable as well
self.x is an instance attribute, not a class attribute. Aslo, the def
statement creates a function, not a method, so the notion of
"class_element" or however you name it is totally irrelevant here.
Once again: how is adding "magical" syntax going to reduce confusion ?
> (confusing the number of arguments to a method
> call).
This is only confusing the first time. The correct solution to this
problem is IMHO to better document Python's object model, specially how
the descriptor protocol turns functions into methods.
As I've said in another reply the argument that "def self.meth( arg )"
is confusing because "self" doesn't exist in the current scope as an
instance is convincing to me. So I no longer like the alternate syntax
mentioned by Guido.
Still, improved error messages would be desirable (concerning the
number of arguments passed to an instance method).
Then count me as +2 on this !-)
Nicely put! :-)
However, $ is sometimes used as an alternative way of writing S̸ (I've
attempted to write here S followed by U+0338 COMBINING LONG SOLIDUS
OVERLAY, in order to produce an S with a stroke through it). This is the
symbol of the "barred subject" in Lacanian psychoanalysis, which is the
Lacanian symbol for the concept of the "self" (see
http://nosubject.com/Bar ).
So, if we want Python to the programming language of choice for Lacanian
psychoanalysts, perhaps we should adopt the symbol "$" (or even, with
Python 3's support for unicode identifiers, S followed by U+0388) instead
of "self."
OK, I'm sold.
:)
> > and friendlier to newbies.
>
> I'd rather say "more acceptable to java-brainwashed developpers".
And I'd rather say you're trolling, but that's ok since you're
preaching to the converted. You conveniently forgot to mention the C++/
Eiffel/Smalltalk/pretty-much-every-OO-lang "brainwashed" developers
too. In reality Python, with its kludgy OO and objects being
essentially glorified dicts, is the odd one out, not the other way
around.
> So, if we want Python to the programming language of choice for Lacanian
> psychoanalysts, perhaps we should adopt the symbol "$" (or even, with
> Python 3's support for unicode identifiers, S followed by U+0388)
> instead of "self."
Is that supposed to be a serious argument or a joke? :)
The advantage of explicit self is to easily differentiate instance
variable with local variable/names. When I need to shorten the code, I'll
simply alias it to a local name, no need for syntax change or new keyword.
class C(object):
def __init__(self):
self.a = 2
self.b = 2
self.c = 3
def x(self):
#return ((-self.b + math.sqrt(self.b**2 - 4 * self.a * self.c)) /
(2 * self.a)), ((-self.b - math.sqrt(self.b**2 - 4 * self.a * self.c)) /
(2 * self.a))
a, b, c = self.a, self.b, self.c
sq = math.sqrt
return ((-b + sq(b**2 - 4*a*c)) / (2*a)), ((-b - sq(b**2 -
4*a*c)) / (2*a))
> On Sat, 6 Dec 2008 23:21:04 -0800 (PST) Lie <Lie....@gmail.com> wrote:
>
>> I think we have to test this on newbies. [snip]
>>
> Now that's talking like a programmer!
>
> Ideas on how such a survey could be conducted? Anyone?
>
>
>> If this dead horse is revived because of that reason, then I'd go with
>> changing the error message to something that is less confusing to
>> newbies[1].
> + googol
>
>
>> I remember being tripped with the (thinking that python miscounted the
>> number of argument) when I was new. This has the advantage of backward
>> compatibility and no syntax change, just less misleading error message.
>>
>> [1] anything could work, but I like this one: (c is an instance of
>> class C)
>> if the code is: c.foo(...), Error: "TypeError: c.foo() takes exactly 3
>> argument"
>> while if the code is: C.foo(...), Error: "C.foo() takes exactly 4
>> arguments"
>> You can implement c.foo as a curried C.foo function, catch C.foo's
>> TypeError exception then reraise it as c.foo exception.
> I'm not sure that I'd find that less confusing. Because a c.foo() *does*
> take four arguments, not three. It's just that the first one is implicit
> (Right?).
It's not implicit, we explicitly pass c (the object instance), although
not in the argument list. So c.foo takes 3 arguments while C.foo takes 4
arguments.
In other words:
from functools import partial
c = C() -> c.attr = partial(C.attr, c)
Note the error message I gave:
"TypeError: c.foo() takes exactly 3 arguments"
"TypeError: C.foo() takes exactly 4 arguments"
There are two differences there, not only one claims to accept three and
the other 4 arguments, but also the capitalization of c/C. Here is a
clearer example:
inst = cls()
"TypeError: inst.foo() takes exactly 3 arguments"
"TypeError: cls.foo() takes exactly 4 arguments"
for comparison, python's current (2.5) error message is:
"TypeError: foo() takes exactly 4 arguments"
in addition, with this proposal we'll know how foo is being called.
The following is a quick and dirty implementation of such error message.
Note: There are still some unresolved problems though:
1. instance.[func name] is hardcoded, as I don't know how to get the
instance's name from the instance creation itself
2. Class Invoking from class gives TypeError: foo()... instead of
TypeError: Class.foo()...
3. most definitely not to be used on real application
from types import MethodType
import re
errmess = re.compile(r'(.*?) (.*?) (\d*) (arguments?) \((\d*) given\)')
def usenewexc(obj):
def wrap(f):
def wrap_(*args, **kargs):
try:
print args, kargs
return f(*args, **kargs)
except TypeError, e:
re_mess = errmess.match(e.message)
fname = re_mess.group(1)
interm = re_mess.group(2) if re_mess.group(3) != '1' else
'takes'
reqargs = int(re_mess.group(3)) - 1 if re_mess.group(3) !
= '1' else 'no'
argue_s = re_mess.group(4) if re_mess.group(3) != '1'
else 'arguments'
givenargs = int(re_mess.group(5)) - 1
raise TypeError('%s.%s %s %s %s (%s given)' %
('instance', fname, interm, reqargs, argue_s, givenargs))
return wrap_
for attrname in dir(obj):
attr = obj.__getattribute__(attrname)
if type(attr) == MethodType:
obj.__setattr__(attrname, wrap(attr))
return obj
class A(object):
def foo(self):
print ''
pass
a = usenewexc(A())
A.foo(a, 2)
Almost, indeed. But not as much as you !-)
I don't really see any advantage. IMHO, it is not clearer, it is not
more concise, it makes the definition of class shared variables look
really out of place. It also makes the new programmer wonder where
the function attaches if you *don't* specify self. I also give it a
-1.
This brings up another question, what would one use when referencing
method names inside the class definition?:
class C:
def self.method(arg):
self.value = arg
def self.othermethod(arg):
self.value = arg
# do this?
funcs = (self.method, self.othermethod)
# or this?
funcs = (method, othermethod)
On another related note, I would be interested in seeing this syntax
adopted for the very purpose Carl hinted at...
Normally, if I'm defining a nested function that needs to be stored as
an object attribute, I have to use a dummy name, like the following:
class C:
def createfunc(self, arg):
def _dummy(arg):
return arg + 1
self.func = _dummy
It would be nice to be able to do the following instead:
class C:
def createfunc(self):
def self.func(arg):
return arg + 1
Or, after the class definition is done, to extend it dynamically:
def C.method(self, arg):
self.value = arg
...which would be the equivalent of the following:
def method(self, arg):
self.value = arg
C.method = method
Since functions are first-class objects, it seems perfectly reasonable
to me.
The above example should have read as follows:
class C:
def createfunc(self, arg):
def self.func(arg):
return arg + 1
-----
Anthony Tolle
> adopted for a different purpose...
>
> Normally, if I'm defining a nested function that needs to be stored as
> an object attribute, I have to use a dummy name, like the following:
>
> class C:
> def createfunc(self, arg):
> def _dummy(arg):
> return arg + 1
> self.func = _dummy
>
> It would be nice to be able to do the following instead:
>
> class C:
> def createfunc(self):
> def self.func(arg):
> return arg + 1
>
> Or, after the class definition is done, to extend it dynamically:
>
> def C.method(self, arg):
> self.value = arg
>
> ...which would be the equivalent of the following:
>
> def method(self, arg):
> self.value = arg
> C.method = method
>
> Since functions are first-class objects, it seems perfectly reasonable
> to me.
> --
> http://mail.python.org/mailman/listinfo/python-list
I agree, this would be much nicer and would not require any special
cases. I'm not convinced that this is needed, but at least this won't
confuse newbies as much.
That's true. But what would a Python-brainwashed developer be?
> class C:
> def createfunc(self):
> def self.func(arg):
> return arg + 1
>
> Or, after the class definition is done, to extend it dynamically:
>
> def C.method(self, arg):
> self.value = arg
>
> ...which would be the equivalent of the following:
>
> def method(self, arg):
> self.value = arg
> C.method = method
What about the following then?
functions = {}
def functions['square'](x):
return x*x
def functions['cube'](x):
return x**3
--
Arnaud
Why not? "def ob.func" is fundamentally "def ob.__dict__["func"]" anyway.
I like this idea much better than the original proposal, even though
it is pretty much unrelated.
Anyone who believes that writing beautiful, unencumbered code is efficient, while still believing that discovering type casting errors at runtime isn't grossly inefficient.
Or given whitespace delimited code, Python developers believe that nothing is important.
;-)
*****
The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential, proprietary, and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from all computers. GA623
I agree that it's an extension (extrapolation) of the 'def self.meth'
notation. For 'func_name', would you use the quoted string? Would
you allow arbitrary expressions for the string, and the dictionary to
add to? For example:
def dict_val( )[ "name%i"% int_val( ) ]( self, arg, arg, arg ): ...
It's not much worse than: (Unproduced)
def anon( self, arg, arg, arg ): ...
dict_val( )[ "name%i"% int_val( ) ]= anon
#or if you really want the target before the def:
@assign( dict_val( ), "name%i"% int_val( ) )
def _( self, arg, arg, arg ): ...
And the latter are already both legal. But there have been PEPs
accepted before that abbreviate 2 lines into 1.
I think it's an awesome proposal. It's about time! With this change,
defining methods uses the same special syntax hack that calling them
does. This is a good thing because it makes it easy to refer to
methods consistently.
I see a lot of people are against it; I admit that it's not the status
quo, but that's not a sufficient argument against a change (it defeats
all possible changes). A more interesting argument against it is that
it's special "implicit" syntax; but I would argue that it merely
reflects the existing special syntax of method calls.
Unfortunately, writing a PEP is sadly outside my skillset.
> Daniel
-Wm
> On another related note, I would be interested in seeing this syntax
> adopted for a different purpose...
>
> class C:
> def createfunc(self):
> def self.func(arg):
> return arg + 1
I agree -- this would be a much better use of the syntax,
and I'd like to see this possibility left open.
--
Greg
-Beautiful is better than ugly.
A bit subjective, but this is ugly IMO.
-Special cases aren't special enough to break the rules.
-There should be one-- and preferably only one --obvious way to do it.
I claim that the burden of proof rests with the author of the
proposal.
except that self doesn't exist when the method is defined. Or, should I
say, when the function is defined - because that's really a function. It
only becomes a method when looked up on the class (either directly or
thru an instance), thanks to the descriptor protocol (hint : there's
*no* "syntax hack" involved when calling inst.method - just partial
evaluation). IOW : this def self.stuff thing only empeds correct
understanding of Python's object model.
(snip)
> I see a lot of people are against it; I admit that it's not the status
> quo, but that's not a sufficient argument against a change (it defeats
> all possible changes). A more interesting argument against it is that
> it's special "implicit" syntax; but I would argue that it merely
> reflects the existing special syntax of method calls.
Once again, there's *nothing* like an "existing special syntax of method
calls". Just the use of the descriptor protocol (the very same mechanism
that's powers properties) and partial application. I've already
described this more than once in details in this newsgroup FWIW.
anthon...@gmail.com wrote:
> On Dec 6, 4:15 pm, Carl Banks <pavlovevide...@gmail.com> wrote:
[...]
>
> This brings up another question, what would one use when referencing
> method names inside the class definition?:
>
> class C:
> def self.method(arg):
> self.value = arg
> def self.othermethod(arg):
> self.value = arg
> # do this?
> funcs = (self.method, self.othermethod)
> # or this?
> funcs = (method, othermethod)
>
> On another related note, I would be interested in seeing this syntax
> adopted for a different purpose...
>
> Normally, if I'm defining a nested function that needs to be stored as
> an object attribute, I have to use a dummy name, like the following:
>
> class C:
> def createfunc(self, arg):
> def _dummy(arg):
> return arg + 1
> self.func = _dummy
>
> It would be nice to be able to do the following instead:
>
> class C:
> def createfunc(self):
> def self.func(arg):
> return arg + 1
>
> Or, after the class definition is done, to extend it dynamically:
>
> def C.method(self, arg):
> self.value = arg
>
> ...which would be the equivalent of the following:
>
> def method(self, arg):
> self.value = arg
> C.method = method
>
> Since functions are first-class objects, it seems perfectly reasonable
> to me.
A decorator might be more advisable here.
class C:
def createfunc(self):
@some_decorator_name
def func(arg):
return arg + 1
Altough I'm not a huge fan of decorators, this would be more in line
what Python already can do an would lean on the @staticmethod and
@classmethod decorators.
Those are operators and the comment starter, not identifiers.
I think that the more used an operator/variable is, the least mnemonic
it' name has to be. Given that you'll be useing it all the time, you
don't need it's name reminding you what it's supposed to be used for.
So the "it's not a speaking-identifier" argument is not a good one, in
my opinion.
However, $ being ugly is a very strong argument. Python is supposed
to be beautiful. And sure you can get used to it, just as you can get
used to Pearl, assembly language or Brainfuck. By beautiful we mean
beautiful at first sight.
-1. In most cases, it would generally be better as:
def functions(x):
return x.func()
since the rule-of-thumb of OOP is that objects should do things by
itself. This is also more in line with python's built-in functions, which
merely calls the appropriate __special__ names.
and whenever creating an object is too complex, that could easily be
def functions(which, x):
def _function_square():
return x*x
def _function_cube():
return x**3
d = {'square': _function_square,
'cube': _function_cube,
}
return d[which]()
Admittedly a tough call. I see the attraction of the proposed syntax.
Maybe somewhat more readable since the declaration syntax matches the
usage syntax, which is nice. I think it would have been superior to the
current syntax if it had been done that way in the first place. However,
since newbies will still have to learn both syntaxes in order to read
other peoples code, it does not simplify the language.
The main thing I don't like about it is that it violates this principle:
"There should be one-- and preferably only one --obvious way to do it."
Ken
Daniel Fetchinson wrote:
> Hi folks,
>
> The story of the explicit self in method definitions has been
> discussed to death and we all know it will stay. However, Guido
> himself acknowledged that an alternative syntax makes perfect sense
> and having both (old and new) in a future version of python is a
> possibility since it maintains backward compatibility. The alternative
> syntax will be syntactic sugar for the old one. This blog post of his
> is what I'm talking about:
>
> http://neopythonic.blogspot.com/2008/10/why-explicit-self-has-to-stay.html
>
> The proposal is to allow this:
>
> class C:
> def self.method( arg ):
> self.value = arg
> return self.value
>
> instead of this:
>
> class C:
> def method( self, arg ):
> self.value = arg
> return self.value
>
> I.e. explicit self stays only the syntax is slightly different and may
> seem attractive to some. As pointed out by Guido classmethods would
> work similarly:
>
> class C:
> @classmethod
> def cls.method( arg ):
> cls.val = arg
> return cls.val
>
> The fact that Guido says,
>
> "Now, I'm not saying that I like this better than the status quo. But
> I like it a lot better than [...] but it has the great advantage that
> it is backward compatible, and can be evolved into a PEP with a
> reference implementation without too much effort."
>
> shows that the proposal is viable.
>
> I'd like this new way of defining methods, what do you guys think?
> Anyone ready for writing a PEP?
>
> Cheers,
> Daniel
>
>