Bengt Richter said:
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')
('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:
... 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
... This uses
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:
x=2, y='3', x*y='33'
x=2, y='7', x*y='77'
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