ASPN ActiveState Programmer Network
ActiveState
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups


Recent Messages
List Archives
About the List
List Leaders
Subscription Options

View Subscriptions
Help

View by Topic
ActiveState
.NET Framework
Open Source
Perl
PHP
Python
Tcl
Web Services
XML & XSLT

View by Category
Database
General
SOAP
System Administration
Tools
User Interfaces
Web Programming
XML Programming


MyASPN >> Mail Archive >> python-dev
python-dev
Re: [Python-Dev] Draft proposal: Implicit self in Python 3.0
by Ian Bicking other posts by this author
Jan 6 2006 9:50AM messages near this date
Re: [Python-Dev] Draft proposal: Implicit self in Python 3.0 | Re: [Python-Dev] Draft proposal: Implicit self in Python 3.0
Nick Coghlan wrote:
[...]
>  Under the proposal being discussed, things become far less clear:
>  
>       class Foo:
>           def __init__(x):         # 1: Implicit self
>               .x = x               # 2: Brief form of: self.x = x
>           def bar(a, b):           # 3: Two arguments...
>               print .x + a + b
>  
>       f = Foo(10).bar              # We agree this accepts 2 arguments
>       f = Foo.bar                  # How many arguments does f accept?
>       f = Foo.__dict__["bar"]      # How many arguments does it accept now?

I think this might return things very similar to what are returned now. 
  The only reasonable alternative I can think of is that Foo.bar would 
return something that simply could not be called until it was bound, so 
this:

   inst = Foo()
   f = Foo.bar
   print f(inst, 1, 2)

would have to be translated to this this:

   inst = Foo()
   f = Foo.bar
   meth = bind(f, inst)
   print meth(1, 2)

It seems clear given the rest of the proposal that this second form will 
work, it's just a question of whether the first form will work at all. 
Personally I find the first form is rather uncommon anyway, and 50% of 
the time I write it it's a bug.  So the more explicit second form would 
be fine with me.  Well... it becomes more complex for decorators, I guess:

   def printargs(func):
       def replacement(*args, **kw):
           print args, kw
           return func(*args, **kw)
       return replacement
   class Foo:
       @printargs
       def null(a): pass

What is printargs going to print?  Will it even work?  I'd guess you'd 
have to do:

   def printargs(func):
       def replacement(*args, **kw):
           print args, kw
           return bind(func, self)(*args, **kw)
       return replacement

But what does that do if you apply printargs to a function that isn't a 
method?  I generally have found it awkard to apply decorators to both 
methods and functions, except when the decorators pass through all the 
arguments unchanged (as printargs does).  But I don't know if this is an 
improvement; I guess it depends on what bind(func, self) does outside of 
a method invocation.  I think self should be undefined in that case. 
Well, I guess you could do:

   def printargs(func):
       def replacement(*args, **kw):
           print args, kw
           try:
               bound = bind(func, self, class)
           except NameError:
               try:
                   bound = bind(func, None, class)
               except NameError:
                   bound = func
           return bound(*args, **kw)
       return replacement

Ugh.

>  The answer to the first question *has* to be 3, or we lose too much 
>  functionality - but that's seriously surprising (the method appears to require 
>  two arguments when its defined, but actually requires 3 due to its being 
>  retrieved from a class). And it still requires that a distinction be made 
>  between instance, class and static methods in order to control the signature 
>  of the retrieved method.
>  
>  However, that answer creates its own problems - what if we have a 3-argument 
>  function that does exactly what we want our method to do? We'd need some way 
>  of signalling to the class that the function should be left alone when being 
>  retrieved from the class, but have the first argument bound automatically when 
>  being retrieved from an instance.
>  
>  This is where the "Explicit is better than implicit" and "Practicality beats 
>  purity" *both* kick in in favour of explicit self and class_ parameters - the 
>  signature of the retrieved function is exactly what the source code says it 
>  is, because there aren't any implicit parameters getting slipped into the 
>  parameter list when you aren't looking.
>  
>  As I see it, the real issue is that people are often coming from a Java or C++ 
>  background where you can't manipulate functions and classes as first-class 
>  objects - the idea that the instance method signature could be written to 
>  describe the signature of the unbound method returned by "Foo.bar" rather than 
>  the bound method returned by "Foo().bar" is an entirely foreign concept.

I disagree; I'm 100% comfortable and have internalized Python's use of 
an explicit self parameter, but it still doesn't feel more explicit or 
practical than the traditional way of writing out methods in other 
languages.  I'm inclined to say that this might be too substantial of a 
change to Python, but I don't think the current way method definitions 
work is particular elegant, and it hasn't really grown on me over all 
these years.  I still frequently spell method signatures incorrectly. 
And I can't explain the current situation to a new user, except to say 
"this is just the way it is", because the explanation only makes sense 
when you are much further into the language.  And don't get me started 
on the error messages when you get the parameter count wrong...


(As an aside directed at the original PEP, I think discussion of leaving 
self out of expressions, e.g., ".x" for "self.x", should be separate 
from the rest of this PEP).


-- 
Ian Bicking  /  ianb@[...].com  /  http://blog.ianbicking.org
_______________________________________________
Python-Dev mailing list
Python-Dev@[...].org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/python-dev-ml%40activestate.c
om
Thread:
Alexander Kozlovsky
Ralf W. Grosse-Kunstleve
Ian Bicking
Thomas Wouters
Tim Peters
Brett Cannon
Fredrik Lundh
Ralf W. Grosse-Kunstleve
Samuele Pedroni
Fredrik Lundh
Ralf W. Grosse-Kunstleve
Thomas Wouters
Ralf W. Grosse-Kunstleve
Phillip J. Eby
Thomas Wouters
Fredrik Lundh
Armin Rigo
Guido van Rossum
Ralf W. Grosse-Kunstleve
"Martin v. Löwis"
"Martin v. Löwis"
Kay Schluehr
Guido van Rossum
Thomas Wouters
Phillip J. Eby
"Martin v. Löwis"
Thomas Wouters
"Martin v. Löwis"
Thomas Wouters
Tim Peters
Ian Bicking
Thomas Wouters
Ian Bicking
Samuele Pedroni
Kay Schluehr
Alexander Kozlovsky
Jim Jewett
Fabien Schwob
Kay Schluehr
Nick Coghlan
Ian Bicking
"Martin v. Löwis"

Privacy Policy | Email Opt-out | Feedback | Syndication
© ActiveState Software Inc. All rights reserved