Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Another try at Python's selfishness

1 view
Skip to first unread message

n.es...@gmx.de

unread,
Feb 2, 2006, 5:08:22 PM2/2/06
to
Having read previous discussions on python-dev I think I'm not the only
Python programmer who doesn't particularly like python's "self"
parameter:

class Foo:
def bar(self, a,b):
return a+b
Foo().bar(1,2) => 3

The main reason (at least for me) is that there's simply too much
"magic" in it. Why does the expression left of the '.' get promoted to
the first parameter? It even goes further:

Foo.bar(Foo(), 1,2)

works, but:

Foo.bar(1,2,3)

doesn't, just because of the "magical first parameter" in a member
function. But:

Foo.__dict["bar"]__(1,2,3)

Does work.

The point is, I _do_ think it's a good idea to explicitly write
"self.SomeMember" for member-access, so I thought: why can't we be
equally explicit about member function declaration? Wouldn't it be nice
if I could write (say, in Python 3k, or maybe later):

class Foo:
def self.bar(a,b):
return a+b
Foo().bar(1,2) => 3

That way, the declaration would match the invocation (at least
syntactically), and the "magic"-feeling is gone. In the long run, the
"old-style" syntax (i.e. if there's no '.' in the method name) could be
used for static methods.

What do you think?

Donn Cave

unread,
Feb 2, 2006, 5:53:53 PM2/2/06
to
In article <1138918102.8...@o13g2000cwo.googlegroups.com>,
n.es...@gmx.de wrote:

I think you make it too complicated. Why shouldn't all
functions be declared and called in the same way, that
would be the simplest thing for everyone.

class Foo
def bar(self, a, b):
return a + b
bar(Foo(), 1, 2) => 3

The virtues of this consistency become more apparent in a
more complex functional context:

sys.stdin.write(open(file, 'r').read().split(sep)[0])

vs.
write(sys.stdin, split(read(open(file, 'r')))[0])

Donn Cave, do...@u.washington.edu

Paul McGuire

unread,
Feb 2, 2006, 6:49:34 PM2/2/06
to
<n.es...@gmx.de> wrote in message
news:1138918102.8...@o13g2000cwo.googlegroups.com...

> Having read previous discussions on python-dev I think I'm not the only
> Python programmer who doesn't particularly like python's "self"
> parameter:
>

How about this decorator-based approach (still need to pick *some* name for
self, I picked "__").

-- Paul

def memberFunction(f):
def func(self,*args,**kwargs):
globals()["__"] = self
return f(*args,**kwargs)
func.__name__ = f.__name__
func.__doc__ = f.__doc__
func.__dict__.update(f.__dict__)
return func


class Test:
@memberFunction
def __init__(x,y):
__.x = x
__.y = y

@memberFunction
def mult():
"Multiply the two member vars"
return __.x * __.y


t = Test(5,4)
print t.mult()
print dir(t)
print t.mult.__doc__

n.es...@gmx.de

unread,
Feb 2, 2006, 7:32:21 PM2/2/06
to
> write(sys.stdin, split(read(open(file, 'r')))[0])

So, if I got you right, the interpreter would have to interpret this
line like this:
1. Evaluate the first parameter of the first function (sys.stdin)
2. Look up the attribute "write" in this object
3. evaluate the first parameter of the split function ->
4. evaluate the first parameter of the read function ->
5. evaluate file (I guess this is a local string variable?)
6. try attribute lookup "open" on the string
7. fail -> call the global "open" function
8. lookup "read" in that object, call it
9. attribute lookup "split" on the returned object
10. call __getitem__(0)
11. pass the parameters to the write function from (1)

Is this correct?
My main problems are that you have to "guess" at step 6/7, and that the
order of evaluation makes me a little dizzy ;-) Also, member functions
seem to "shadow" global ones, what if I wanted to use some global
"split" function I've written myself instead of the string's one. If I
was mean, I'd ask you what this one does:
class A:
def test(self, this): return 1
class B:
def test(this, self): return 2
test(self=A(), this=B())

The current call syntax at least can be read from left-to-right, and
you always know whether you call a member function or a global one.

n.es...@gmx.de

unread,
Feb 2, 2006, 7:56:06 PM2/2/06
to
Definitely looks interesting. I'd like it more if it was more explicit,
but still, it does look nice.

I guess you could make it recursion-safe if you saved/restored the
global "__" variable before/after calling the actual function, and
probably there's a way to make it thread-safe, too. But how would you
make it generator-safe? Also, wouldn't lambda's you pass around from
object to object be bound to use the wrong instance? How would you fix
this code:

class TestA:
@memberFunction
def do(f):
print f()


class TestB:
@memberFunction
def do(x):
x.do(lambda : __)

TestB().do(TestA()) # should print out TestB, does print out TestA


There really should be something like a wiki for
"selfishness"-proposals with pros and cons, so I could have looked at
some before thinking about my own one...

DH

unread,
Feb 2, 2006, 8:27:55 PM2/2/06
to

That's similar to ruby. Really this isn't going to change in python,
at least not anytime soon. If it really bothers you, then ruby is
something to look into.
But I think most people who don't like the extraneous 'self' in python
just consider it a minor inconvenience and don't even notice it after
using python for a while. It is only when you switch between python and
other languages that you notice it again.

If python extends decorators to allow them to be applied to classes as
well as functions (which is more likely to happen perhaps), then you'll
see a bunch of useful hacks pop up to eliminate the need for 'self' in
method declarations.

Donn Cave

unread,
Feb 2, 2006, 8:32:58 PM2/2/06
to
In article <1138926741.0...@z14g2000cwz.googlegroups.com>,

That usage (self is second parameter to B.test) is bound
to cause trouble in general, but in this case doesn't have
any effect I can see. The function call "test" would be
resolved from its first parameter, instance of A, and that
function would return 1. One of us is missing something
here, could be me.

>
> The current call syntax at least can be read from left-to-right, and
> you always know whether you call a member function or a global one.

That's exactly the problem, it doesn't read from left to right,
because we swap back and forth between function(parameter and
parameter.function notation. It only works if you don't have
to mix the two. I'm saying, pick one and use it consistently.

Donn Cave, do...@u.washington.edu

Paul McGuire

unread,
Feb 2, 2006, 11:20:23 PM2/2/06
to
<n.es...@gmx.de> wrote in message
news:1138928166....@g44g2000cwa.googlegroups.com...
Here's another pass:

__ = None #initialize global __
def memberFunction(f):
def func(self,*args,**kwargs):
global __
save__ = __
globals()["__"] = self
try:
return f(*args,**kwargs)
finally:
__ = save__

func.__name__ = f.__name__
func.__doc__ = f.__doc__
func.__dict__.update(f.__dict__)
return func


class Test:
@memberFunction
def __init__(x,y):
__.x = x
__.y = y

@memberFunction
def mult():
"Multiply the two member vars"
return __.x * __.y


t = Test(5,4)
print t.mult()
print dir(t)
print t.mult.__doc__

class TestA:


@memberFunction
def do(f):
print f()


class TestB:
@memberFunction
def do(x):

z = __ # lambda's shouldn't directly reference '__'
x.do(lambda : z)

TestB().do(TestA())

Prints out:
20
['__doc__', '__init__', '__module__', 'mult', 'x', 'y']


Multiply the two member vars

<__main__.TestB instance at 0x009DA4E0>

Terry Hancock

unread,
Feb 3, 2006, 1:06:32 AM2/3/06
to pytho...@python.org
On Thu, 02 Feb 2006 19:27:55 -0600
DH <n...@spam.com> wrote:
> But I think most people who don't like the extraneous
> 'self' in python just consider it a minor inconvenience
> and don't even notice it after using python for a while.

After messing around with Javascript (many magical
variables that suddenly show up in your namespaces!), I
began to *seriously* appreciate Python's design. Having
self as an explicit parameter is beautiful self-documenting
design.

The convention that the self parameter is always "self" with
4 characters instead of, say, __ or _ or s can get annoying,
but of course, you are actually free to break this
convention. The advantage to keeping it, of course, is that
anybody can google "python self" and immediately get an
explanation of what it is, whereas googling for "python _"
is less likely to be helpful.

In fact, I think this ease of finding documentation is one
of the reasons why Python's heavy use of keywords (rather
than symbolic operators) is so useful. Recent additions like
"list comprehensions" and "generators" create a lot of
newbie confusion not least because newbies simply don't know
that [x for x in mylist] is *called* a "list comprehension"
(if they knew what it was called, they'd answer the question
for themselves).

They see the code and don't have any idea what it is. It
adds to the basic or core knowledge that you have to wade
through before you can say you "know Python" even at the
trivial level.

One of the things that attracted me to Python (at v1.5.2)
was the fact that the core language was so small and simple
that I could learn it in just a few days. The more
syntactical sugar added, the less that will be true, though.

I don't think we've busted the system yet, but I think
there's some reason for caution against making things any
*more* complicated. I still see "newbie-friendliness" as a
MAJOR plus for Python -- it increases the chance that users
of your software will become contributors.

I mean, even Perl was probably pretty simple in the
beginning. ;-)

--
Terry Hancock (han...@AnansiSpaceworks.com)
Anansi Spaceworks http://www.AnansiSpaceworks.com

Magnus Lycka

unread,
Feb 3, 2006, 6:00:52 AM2/3/06
to
n.es...@gmx.de wrote:
> What do you think?

The impression I get from your suggestion is that you
haven't really understood Python. I'm sure that some
things could be better designed or better documented,
but your suggestions would actually make things worse.
Sorry.

Today, Python has a syntactic shortcut. If 'a' is an
instance of class 'A', a.f(x,y,z) is a shortcut for
A.f(a,x,y,z). If you don't use the shortcut, there is
no magic at all, just the unusual occurence of a type
check in Python! If you use the shortcut, Python code
looks just like most other OO languages. This isn't
very magical.

What you suggest doesn't remove magic, but it introduces
a bunch of inconsistencies!

> But:
> Foo.__dict["bar"]__(1,2,3)
> Does work.

I agree that this isn't completely clean, and there are
some other ways in which the distinction between functions,
unbound methods and bound methods seem a bit quirky to me.
I don't think the problem is in the syntax though, and if
it had been a real problem, it would had been solved.

> class Foo:
> def self.bar(a,b):
> return a+b
> Foo().bar(1,2) => 3

First of all, you are using a really poor example of a "method",
since it doesn't use any attributes of the Foo instance. That
function doesn't seem to belong in that class at all. If it
should be in the class, it should be a static method, so self
should not be involved at all. In modern Python it would look
like this:

class Foo(object):
@staticmethod
def bar(a, b):
return a+b

Anyway, my impression is that you haven't fully understood how
namespaces work in Python, at least not the distinction between
class namespaces and instance namespaces. Please study this a
bit more. Hopefully, you'll find enlightenment and things will
fall into place for you.

You are really giving "self" a magic meaning with your suggestion
which isn't needed at all. So far, the existence of x.y somewhere
in Python always implied that x was already introduced explicitly
in the program, and you suggest that we violate that both in the
"def self.x"-row, and inside the methods when we access attributes.

Provoking a language can be a way of learning it, and provoking
people can sometimes lead to new insights, but it's important to
have an open mind. When learning a new language, it's probably
better to try to adapt oneself to it, rather than the other way
around.

n.es...@gmx.de

unread,
Feb 3, 2006, 6:23:00 AM2/3/06
to
> That usage (self is second parameter to B.test) is bound
> to cause trouble in general, but in this case doesn't have
> any effect I can see. The function call "test" would be
> resolved from its first parameter, instance of A, and that
> function would return 1. One of us is missing something
> here, could be me.

Probably my example wasn't clear, let's try another:

class A:
def test(a, **kwargs): return 1
class B:
def test(b, **kwargs): return 2
test(a=A(), b=B())

"self" isn't a keyword, so nothing should forbid this code. What is the
interpreter to do if it stumbles across this "test" call? I mean,
named-argument lookup is a tricky thing even if you do know what
function you're calling. If this would depend on one of the parameters,
I think it would become completely unintelligible. (you can think of
more complex examples yourself)

> That's exactly the problem, it doesn't read from left to right,
> because we swap back and forth between function(parameter and
> parameter.function notation.

That's because they're doing two different things: object.method() does
an attribute lookup, while function(parameter) looks for the function
in the current scope.

n.es...@gmx.de

unread,
Feb 3, 2006, 6:35:25 AM2/3/06
to
Yes, that's what I had in mind when I said it could be made
recursion-safe. It's still not thread-safe, but I think that could be
done too, using thread-local-variables instead of globals.

> class TestB:
> @memberFunction
> def do(x):
> z = __ # lambda's shouldn't directly reference '__'
> x.do(lambda : z)

Yes, that's what I meant when I said it wasn't lambda-safe. That means
a completely legal and (in my code) common expression can behave
totally unexpected. Would be a no-go for me.

But I think it gets worse:

class TestA:
@memberFunction
def do():
yield 1
yield 2
yield __


class TestB:
@memberFunction
def bar():
for x in TestA().do():
print x

TestB().bar()

Doesn't behave as expected, and the only way I can see to fix it would
be to declare a local function inside TestA's "do" function...

Steven D'Aprano

unread,
Feb 3, 2006, 6:51:15 AM2/3/06
to
On Fri, 03 Feb 2006 12:00:52 +0100, Magnus Lycka wrote:

> Today, Python has a syntactic shortcut. If 'a' is an
> instance of class 'A', a.f(x,y,z) is a shortcut for
> A.f(a,x,y,z).

It is easy to work around (break?) that behaviour:

class A(object):
def foo(self):
print "normal method foo"

a = A()

def foo(self):
print "special method foo"

from new import instancemethod
a.foo = instancemethod(foo, a)

Now we can see that a.foo() is no longer a shortcut for A.foo(a):

>>> a.foo()
special method foo
>>> A.foo(a)
normal method foo


So instances can have methods that they don't inherit from their class!

--
Steven.

n.es...@gmx.de

unread,
Feb 3, 2006, 6:51:03 AM2/3/06
to
> First of all, you are using a really poor example of a "method",
> since it doesn't use any attributes of the Foo instance.

Agreed. I tried to post a short example, and it obviously was to short
to make my point clear. lets take a longer one. Current syntax:

class Pair:
def __init__(self, a,b):
self.a = a
self.b = b

def sum(self):
return self.a + self.b

def product (this):
return this.a + this.b

My alternative syntax suggestion would be this one:

class Pair:
def self.__init__(a,b):
self.a = a
self.b = b

def self.sum():
return self.a + self.b

def this.product ():
return this.a + this.b

> You are really giving "self" a magic meaning with your suggestion
> which isn't needed at all.

No. I hope this is clearer in the example above. "self" shouldn't be a
keyword. It's a special kind of argument now, so why shouldn't we
explicitly _declare_ that it's a special kind of argument? (as explicit
is better than implicit)

> So far, the existence of x.y somewhere
> in Python always implied that x was already introduced explicitly
> in the program,

Yes, but y(x) also implies that x and y have been introduced explicitly
before, unless it's in a "def" statement. The def statement always
introduces new variables.

> and you suggest that we violate that both in the
> "def self.x"-row, and inside the methods when we access attributes.

def x(self):
declares two new identifiers, "x" and "self"

Why shouldn't
def self.x():
declare two new identifiers ("x" and "self"), too?

Attribute acces wouldn't change.

n.es...@gmx.de

unread,
Feb 3, 2006, 6:59:10 AM2/3/06
to
> I still see "newbie-friendliness" as a
> MAJOR plus for Python -- it increases the chance that users
> of your software will become contributors.

Yes, I 100% agree to that point!
But the point is, the current situation is not newbie-friendly (I can
tell, I am a newbie): I declare a method with 3 parameters but when I
call it I only pass 2 parameters. That's confusing. If I declare a
member variable, I write: "self.x = ValueForX", why can't I be equally
explicit for declaring member functions?

Steven D'Aprano

unread,
Feb 3, 2006, 6:57:36 AM2/3/06
to
On Fri, 03 Feb 2006 03:23:00 -0800, n.estner wrote:

>> That usage (self is second parameter to B.test) is bound
>> to cause trouble in general, but in this case doesn't have
>> any effect I can see. The function call "test" would be
>> resolved from its first parameter, instance of A, and that
>> function would return 1. One of us is missing something
>> here, could be me.
>
> Probably my example wasn't clear, let's try another:
>
> class A:
> def test(a, **kwargs): return 1
> class B:
> def test(b, **kwargs): return 2
> test(a=A(), b=B())
>
> "self" isn't a keyword, so nothing should forbid this code. What is the
> interpreter to do if it stumbles across this "test" call?

You could try running it to see:

>>> class A:
... def test(a, **kwargs): return 1
...
>>> class B:
... def test(b, **kwargs): return 2
...
>>> test(a=A(), b=B())
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'test' is not defined


Oops! You have defined a name "test" in two namespaces, the class A and
the class B, but there is no name "test" in the global namespace you are
trying to run it in.

Since namespaces are critical to Python, your test code is a problem that
just cannot happen in Python. It is a non-issue. Python will not get
confused between the two definitions of test.

> I mean,
> named-argument lookup is a tricky thing even if you do know what
> function you're calling. If this would depend on one of the parameters,
> I think it would become completely unintelligible. (you can think of
> more complex examples yourself)
>
>> That's exactly the problem, it doesn't read from left to right,
>> because we swap back and forth between function(parameter and
>> parameter.function notation.
>
> That's because they're doing two different things: object.method() does
> an attribute lookup, while function(parameter) looks for the function
> in the current scope.

No, function(parameter) does not look for a function. It looks for any
object at all, and then tries to call it.

Both calls do almost the same thing. object.method() looks up the name
"method" in the object namespace, function(parameter) looks up the name
"function" in the current namespace. Neither "method" nor "function" must
be methods or functions, although if they are not callable objects,
calling them will raise an exception. But regardless of what sort of
objects they are, the look up proceeds in the same fashion.

Unless you understand namespaces, you don't understand Python, and any
criticism is likely to be due to misunderstanding.


As near as I can tell, your original complaint might be solved simply: it
seems to me that you are concerned about that extraneous "self" parameter
for methods that don't need it:

class Foo:
def bar(self, a,b):
return a+b
Foo().bar(1,2) => 3

If bar doesn't need the instance or class Foo, perhaps it would be better
off as an ordinary function rather than bound to a class.

But if bar does need to be a method, perhaps you want something like this:


# for Python 2.2 and up
class Foo:
def bar(a,b):
return a+b
bar = staticmethod(bar)

# for Python 2.4 and up
class Foo:
@staticmethod
def bar(a,b):
return a+b

Foo().bar(1,2) works exactly the same as before, but your definition of
bar doesn't need that extraneous "self" parameter.


--
Steven.

n.es...@gmx.de

unread,
Feb 3, 2006, 7:14:33 AM2/3/06
to
> You could try running it to see:
>
> >>> class A:
>
> ... def test(a, **kwargs): return 1
> ...
> >>> class B:
>
> ... def test(b, **kwargs): return 2
> ...
> >>> test(a=A(), b=B())
>
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> NameError: name 'test' is not defined
>
> Oops! You have defined a name "test" in two namespaces, the class A and
> the class B, but there is no name "test" in the global namespace you are
> trying to run it in.
>
> Since namespaces are critical to Python, your test code is a problem that
> just cannot happen in Python. It is a non-issue. Python will not get
> confused between the two definitions of test.

I've been answering to Donn Cave's suggestion. Read it, and you will
understand what I mean.

> As near as I can tell, your original complaint might be solved simply: it
> seems to me that you are concerned about that extraneous "self" parameter
> for methods that don't need it:

No, I wasn't talking about functions that don't use the "self"
parameter. I rarely ever have such functions. I just tried to make the
example as short as possible.

Antoon Pardon

unread,
Feb 3, 2006, 7:22:35 AM2/3/06
to
Op 2006-02-03, n.es...@gmx.de schreef <n.es...@gmx.de>:

Self is not a special kind of argument. It is the accessing of the
method that provides for the magic. Simplified one could say the
following is happening.

def _Pair__init__(self, a, b):


self.a = a
self.b = b

def _Pair_sum(self):
return self.a + self.b

def _Pair_product(this):
return this.a * this.be

class Pair:

def __init__(self, ...):
self.__init__ = BoundMethod(self, _Pair__init__)
self.sum = BoundMethod(self, _Pair_sum)
self.product = BoundMethod(self, _Pair_product)
self.__init__(...)


So when p is an instance of Pair, p.sum is not your defined
function but a BoundMethod.

--
Antoon Pardon

Steven D'Aprano

unread,
Feb 3, 2006, 7:29:56 AM2/3/06
to
On Fri, 03 Feb 2006 04:14:33 -0800, n.estner wrote:

[snip]

>> Since namespaces are critical to Python, your test code is a problem that
>> just cannot happen in Python. It is a non-issue. Python will not get
>> confused between the two definitions of test.
>
> I've been answering to Donn Cave's suggestion. Read it, and you will
> understand what I mean.

Your reply came through as I was writing my reply, and it does help
explain your position better.

>> As near as I can tell, your original complaint might be solved simply: it
>> seems to me that you are concerned about that extraneous "self" parameter
>> for methods that don't need it:
>
> No, I wasn't talking about functions that don't use the "self"
> parameter. I rarely ever have such functions. I just tried to make the
> example as short as possible.

I understand that now :-)

--
Steven.

Steven D'Aprano

unread,
Feb 3, 2006, 7:32:47 AM2/3/06
to
On Fri, 03 Feb 2006 03:51:03 -0800, n.estner wrote:

> My alternative syntax suggestion would be this one:
>
> class Pair:
> def self.__init__(a,b):
> self.a = a
> self.b = b
>
> def self.sum():
> return self.a + self.b
>
> def this.product ():
> return this.a + this.b

This would be a fairly major change to Python, so I think we can say right
up front that the chances of this happening before Python 3 are zero, and
even in Python 3 the chances are about the same as the chances of Richard
Stallman suddenly announcing that he's taken a job for Microsoft writing
Digital Restrictions Management software.

But still, let's continue. After all, all you have to do is convince Guido
that this syntax is better...


>> You are really giving "self" a magic meaning with your suggestion
>> which isn't needed at all.
>
> No. I hope this is clearer in the example above. "self" shouldn't be a
> keyword.

Which it isn't now either.


> It's a special kind of argument now, so why shouldn't we
> explicitly _declare_ that it's a special kind of argument? (as explicit
> is better than implicit)

And a foolish consistency is the hobgoblin of little minds *wink*

[snip]

> def x(self):
> declares two new identifiers, "x" and "self"
>
> Why shouldn't
> def self.x():
> declare two new identifiers ("x" and "self"), too?

Sure, but now the call foo.bar has special meaning inside a def statement
than elsewhere. Elsewhere, foo.bar is an attribute access, looking up
attribute bar in foo's namespace. Using your syntax, in a def statement
foo.bar is a pair of declarations: it declares a name "foo", and it
declares a second name "bar".

This inconsistency is, I think, worse than the implicit use of self.


--
Steven.

Steven D'Aprano

unread,
Feb 3, 2006, 7:55:18 AM2/3/06
to
On Fri, 03 Feb 2006 03:59:10 -0800, n.estner wrote:

>> I still see "newbie-friendliness" as a
>> MAJOR plus for Python -- it increases the chance that users
>> of your software will become contributors.
>
> Yes, I 100% agree to that point!
> But the point is, the current situation is not newbie-friendly (I can
> tell, I am a newbie): I declare a method with 3 parameters but when I
> call it I only pass 2 parameters. That's confusing.

Yes, I understand what you mean now. When I was a newbie, it took me a
little while to get the difference between ordinary functions and methods
too, although I had little OO experience before Python. I don't know if
that helped or hindered the learning experience.

With the current syntax, you have to learn some special behaviour:

class Foo:
def bar(self, x, y):
pass

but you call Foo().bar(x, y)

But with your syntax, you still have to learn special behaviour:


# outside the class definition
self.bar # look up "bar" in self's namespace. self must already exist.

# inside a class definition
class Foo:

self = Something() # normal class attribute "self" created
# this works because self is not a keyword
# Foo now has an attribute "self"

def self.bar(x, y):
# create a method "bar" with "self" in bar's namespace
# Foo now has an attribute "bar" (which is a method)
pass

self.bar = None # normal attribute access
# Foo attribute "self" is modified to have an attribute "bar"

# there is no conflict between self the attribute and self the
# special parameter because they live in different namespaces
# but looking at them, there is an apparent conflict


So, most of the time, foo.bar looks up attribute "bar" in foo; but in a
method definition, foo.bar assigns attribute "foo" in bar. That's special
behaviour too, and it seems to me probably harder to live with and even
more confusing than the behaviour you aim to remove.

--
Steven.

Ben Sizer

unread,
Feb 3, 2006, 9:02:13 AM2/3/06
to

n.es...@gmx.de wrote:
> The main reason (at least for me) is that there's simply too much
> "magic" in it. Why does the expression left of the '.' get promoted to
> the first parameter?

One of the reasons I like Lua is because it doesn't do this, instead
using the : operator to designate method-style calls.

eg.
a:foo(b, c) -- looks up foo within a, and calls it with (a, b, c) as
parameters
a.foo(b, c) -- looks up foo within a, and calls it with (b,c) as
parameters

This means there doesn't need to be a distinction between methods and
functions, just a different operator to treat a function as if it was a
method.

When I started out in Python I figured that I could just assign
functions to objects and treat them then as if they were methods, as I
would in Lua, but quickly learned that it wasn't that simple.

--
Ben Sizer

Antoon Pardon

unread,
Feb 3, 2006, 9:53:12 AM2/3/06
to
Op 2006-02-03, Ben Sizer schreef <kyl...@gmail.com>:

>
> n.es...@gmx.de wrote:
>> The main reason (at least for me) is that there's simply too much
>> "magic" in it. Why does the expression left of the '.' get promoted to
>> the first parameter?
>
> One of the reasons I like Lua is because it doesn't do this, instead
> using the : operator to designate method-style calls.
>
> eg.
> a:foo(b, c) -- looks up foo within a, and calls it with (a, b, c) as
> parameters
> a.foo(b, c) -- looks up foo within a, and calls it with (b,c) as
> parameters
>
> This means there doesn't need to be a distinction between methods and
> functions, just a different operator to treat a function as if it was a
> method.

That is nice. I wonder if the following is possible in Lua:

fun = a:foo
fun(b, c)

with the same effect as:

a:foo(b, c)

--
Antoon Pardon

bruno at modulix

unread,
Feb 3, 2006, 10:09:25 AM2/3/06
to
n.es...@gmx.de wrote:
> Having read previous discussions on python-dev I think I'm not the only
> Python programmer who doesn't particularly like python's "self"
> parameter:

bang ! You're dead !

(no no, just kidding !-)

>
> class Foo:

old-style classes are deprecated.

class Foo(object):

> def bar(self, a,b):
> return a+b


(snip)

> The point is, I _do_ think it's a good idea to explicitly write
> "self.SomeMember" for member-access,

With Python's lookup rules, it couldn't be otherwise anyway !-)

> so I thought: why can't we be
> equally explicit about member function declaration?

Because there's no such thing as a "member function" in Python.

> Wouldn't it be nice
> if I could write (say, in Python 3k, or maybe later):
>
> class Foo:
> def self.bar(a,b):
> return a+b
> Foo().bar(1,2) => 3

'bar' is not an instance attribute, but a class attribute - it belongs
to *class* Foo, not to an instance of Foo.

BTW, 'self' does not yet exist (and cannot possibly exist) when this
code is eval'd (how could an instance of class Foo exists before class
Foo itself exists ?).

> That way, the declaration would match the invocation (at least
> syntactically), and the "magic"-feeling is gone. In the long run, the
> "old-style" syntax (i.e. if there's no '.' in the method name) could be
> used for static methods.

s/static/class/

> What do you think?

That you should learn more about the inners of Python's object model
(and specially at the Descriptor protocol).

class Foo(object):
def __init__(self, a):
self.a = a

def bar(obj, b):
return obj.a + b

f = Foo(1)
bar(f, 2)

Foo.bar = bar
Foo.bar(f, 2)
f.bar(2)

The only 'magic' here is that when bar() is called *as an attribute of a
Foo instance*, the instance is passed as the first parameter. In fact,
this is much more explicit (well, IMHO) than the 'this' reference in
Java or C++.

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'on...@xiludom.gro'.split('@')])"

Alex Martelli

unread,
Feb 3, 2006, 10:29:40 AM2/3/06
to
Magnus Lycka <ly...@carmen.se> wrote:
...

> which isn't needed at all. So far, the existence of x.y somewhere
> in Python always implied that x was already introduced explicitly
> in the program, and you suggest that we violate that both in the

Almost... import (and from) statements are exceptions to this.

import x.y

binds or rebinds name x "on the fly", as well as attribute y of x.


Alex

Alex Martelli

unread,
Feb 3, 2006, 10:40:38 AM2/3/06
to
Steven D'Aprano <st...@REMOVETHIScyber.com.au> wrote:
...

> > Why shouldn't
> > def self.x():
> > declare two new identifiers ("x" and "self"), too?
>
> Sure, but now the call foo.bar

"call"?

> has special meaning inside a def statement
> than elsewhere. Elsewhere, foo.bar is an attribute access, looking up
> attribute bar in foo's namespace.

or setting it, as in foo.bar=23, or setting both names, as in

import foo.bar

> Using your syntax, in a def statement
> foo.bar is a pair of declarations: it declares a name "foo", and it
> declares a second name "bar".

"declares" isn't really pythonic -- let's talk about binding or setting
names, instead.

> This inconsistency is, I think, worse than the implicit use of self.

I don't think there's any inconsistency in deciding that syntax x.y has
different meanings (as to what gets looked up or bound) in different
contexts, because it already does: mostly "look up y in namespace x",
but in x.y=... it's "bind y in namespace x" and in "import x.y" it's
"bind x AND then bind y in namespace y".

Since "def x.y(..." is currently a syntax error, it would introduce no
backwards compatibility to assign a meaning to it. Since the 'def'
statement binds something to the name that follows it (which currently
must be a plain identifier), that's what it should do if it allowed the
following name to be a compound one, too.

Unfortunately, none of this suggests that it's reasonable to have

def x.y(z): ...

mean the same as

def y(x, z): ...

and I have no idea of how it would generalize to def x.y.z(t): ...
(while import x.y.z generalizes in a pretty obvious way wrt import x.y).

So, I'm not supporting the OP's idea; just rejecting the specific
objections to it.


Alex

Steven D'Aprano

unread,
Feb 3, 2006, 11:36:02 AM2/3/06
to
On Fri, 03 Feb 2006 07:40:38 -0800, Alex Martelli wrote:

> Steven D'Aprano <st...@REMOVETHIScyber.com.au> wrote:
> ...
>> > Why shouldn't
>> > def self.x():
>> > declare two new identifiers ("x" and "self"), too?
>>
>> Sure, but now the call foo.bar
>
> "call"?

Call? Who said anything about a call?

*wink*

Okay, poor choice of words. I'm not exactly sure what a better choice
would be. Token? Too specific. Maybe it would have been better to just
have just said "...but now foo.bar has ...".


>> has special meaning inside a def statement
>> than elsewhere. Elsewhere, foo.bar is an attribute access, looking up
>> attribute bar in foo's namespace.
>
> or setting it, as in foo.bar=23,

Conceptually, both setting and getting an attribute involves a "look up"
in the general sense: you need to look up the attribute to get its value,
or to find out where to put its value. You are correct (of course!) that
foo.bar can either be a get or a set, but I'm doing lots of hand-waving
here and I didn't think it was necessary to get bogged down in too much
detail.

> or setting both names, as in
>
> import foo.bar

Ah, I completely forgot about import. But see below.


>> Using your syntax, in a def statement
>> foo.bar is a pair of declarations: it declares a name "foo", and it
>> declares a second name "bar".
>
> "declares" isn't really pythonic -- let's talk about binding or setting
> names, instead.

Yes, you're right, it is a bad habit. Years of Pascal don't die easily.

>> This inconsistency is, I think, worse than the implicit use of self.
>
> I don't think there's any inconsistency in deciding that syntax x.y has
> different meanings (as to what gets looked up or bound) in different
> contexts, because it already does: mostly "look up y in namespace x",
> but in x.y=... it's "bind y in namespace x"

Which from my perspective are conceptually two sides of the coin. The
model I have is "y" is a label in some namespace x, and you have to (in
some sense) look up where "y" should go regardless of whether you are
setting the value or getting the value.

Do you think this model is so far from the actual behaviour of Python that
it is useless? Or is it fair to lump getting and setting attributes/names
together?


> and in "import x.y" it's
> "bind x AND then bind y in namespace y".

I assume that's a typo and you mean "bind y in namespace x".

But even "import x.y" is conceptually a lookup, equivalent to x.y =
__import__("x.y"), with the understanding that x = __import__("x") is
automagically run first.

[hand-waving, hand-waving, hand-waving... of course imports do a lot more
than just setting a name in a namespace]

But in all three of:

foo.bar = something
something = foo.bar
import foo.bar

the hierarchy goes from left to right, with bar being "inside" foo, for
some meaning of inside. The Original Poster's syntax would reverse that,
with def foo.bar(x,y) creating parameter foo "inside" method bar.

--
Steven.

n.es...@gmx.de

unread,
Feb 3, 2006, 11:58:56 AM2/3/06
to
> ...

> Unfortunately, none of this suggests that it's reasonable to have
>
> def x.y(z): ...
>
> mean the same as
>
> def y(x, z): ...

Actually, it shouldn't. The idea was, that
def x.y(z): ...
(explicitly) introduces an unbound method. That's not introducing a new
conect to python, it's just making the difference between an unbound
method and a not-bindable function explicit.

Currently, "def(x,y): ..." can mean two different things: In the
context of a class, it introduces an unbound method, in global or local
contexts it introduces a function. I don't want to have a new syntax
for that, I want two different syntaxes for these two different
meanings.

> and I have no idea of how it would generalize to def x.y.z(t): ...

Nor do I. Is that a problem?

Jean-Paul Calderone

unread,
Feb 3, 2006, 1:24:48 PM2/3/06
to pytho...@python.org, n.es...@gmx.de
On 3 Feb 2006 08:58:56 -0800, n.es...@gmx.de wrote:
>> ...
>> Unfortunately, none of this suggests that it's reasonable to have
>>
>> def x.y(z): ...
>>
>> mean the same as
>>
>> def y(x, z): ...
>
>Actually, it shouldn't. The idea was, that
> def x.y(z): ...
>(explicitly) introduces an unbound method. That's not introducing a new
>conect to python, it's just making the difference between an unbound
>method and a not-bindable function explicit.
>
>Currently, "def(x,y): ..." can mean two different things: In the
>context of a class, it introduces an unbound method, in global or local
>contexts it introduces a function. I don't want to have a new syntax
>for that, I want two different syntaxes for these two different
>meanings.
>

Are you sure you actually understand what's going on?

Python 2.4.2 (#2, Sep 30 2005, 21:19:01)
[GCC 4.0.2 20050808 (prerelease) (Ubuntu 4.0.1-4ubuntu8)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def foo(): pass
...
>>> print type(foo)
<type 'function'>
>>> class bar:
... def foo(self): pass
... print type(foo)
...
<type 'function'>
>>> print type(bar.foo)
<type 'instancemethod'>

Jean-Paul

Donn Cave

unread,
Feb 3, 2006, 1:47:48 PM2/3/06
to
In article <1138965780....@o13g2000cwo.googlegroups.com>,
n.es...@gmx.de wrote:

> > That usage (self is second parameter to B.test) is bound
> > to cause trouble in general, but in this case doesn't have
> > any effect I can see. The function call "test" would be
> > resolved from its first parameter, instance of A, and that
> > function would return 1. One of us is missing something
> > here, could be me.
>
> Probably my example wasn't clear, let's try another:
>
> class A:
> def test(a, **kwargs): return 1
> class B:
> def test(b, **kwargs): return 2
> test(a=A(), b=B())
>
> "self" isn't a keyword, so nothing should forbid this code. What is the
> interpreter to do if it stumbles across this "test" call? I mean,
> named-argument lookup is a tricky thing even if you do know what
> function you're calling. If this would depend on one of the parameters,
> I think it would become completely unintelligible. (you can think of
> more complex examples yourself)

Still see no problem. Of course, it goes without saying that
Python 2.4 doesn't work this way, but given that it's theoretically
possible for f(a) to be resolved similarly to a.f, then I really
do not see what you're seeing here. The kwargs parameter appears
irrelevant from where I'm sitting.

> > That's exactly the problem, it doesn't read from left to right,
> > because we swap back and forth between function(parameter and
> > parameter.function notation.
>
> That's because they're doing two different things: object.method() does
> an attribute lookup, while function(parameter) looks for the function
> in the current scope.

But current scope is actually a compound lookup - function scope,
global scope etc. Generalize it to object scope, and then you
can have a notation that expresses these things consistently - QED.

Donn Cave, do...@u.washington.edu

Terry Reedy

unread,
Feb 3, 2006, 3:27:51 PM2/3/06
to pytho...@python.org

"Magnus Lycka" <ly...@carmen.se> wrote in message
news:drvd56$nb3$1...@wake.carmen.se...

> n.es...@gmx.de wrote:
> Today, Python has a syntactic shortcut. If 'a' is an
> instance of class 'A', a.f(x,y,z) is a shortcut for
> A.f(a,x,y,z). If you don't use the shortcut, there is
> no magic at all, just the unusual occurence of a type
> check in Python!

As was once pointed out to me some years ago, when I wrote something
similar, a.f() is not just a shortcut for A.f(a) [a.__class__.f(a)]. The
latter only looks for f in the class A namespace while the former also
looks in superclass namespaces. The 'magical' part of accessing functions
via instances is the implementation of dynamic inheritance.

Terry Jan Reedy

Jean-Paul Calderone

unread,
Feb 3, 2006, 4:14:26 PM2/3/06
to pytho...@python.org

I'm not sure I follow. Surely you're not suggesting that this doesn't work:

>>> class X:
... def foo(self):
... print 'X.foo', self
...
>>> class A(X):
... pass
...
>>> o = A()
>>> A.foo(o)
X.foo <__main__.A instance at 0xb7cab64c>
>>>

But I can't think what else you might mean.

>
>Terry Jan Reedy
>
>
>
>--
>http://mail.python.org/mailman/listinfo/python-list
>

n.es...@gmx.de

unread,
Feb 3, 2006, 6:48:09 PM2/3/06
to
> Still see no problem. Of course, it goes without saying that
> Python 2.4 doesn't work this way, but given that it's theoretically
> possible for f(a) to be resolved similarly to a.f, then I really
> do not see what you're seeing here. The kwargs parameter appears
> irrelevant from where I'm sitting.

Then either you didn't understand my answers, or I didn't understand
your idea. Could you summarize how exactly "f(x,y=z)" should be
resolved, i.e. where it should look for "f"?

Alex Martelli

unread,
Feb 3, 2006, 11:24:24 PM2/3/06
to
Steven D'Aprano <st...@REMOVETHIScyber.com.au> wrote:
...
> would be. Token? Too specific. Maybe it would have been better to just
> have just said "...but now foo.bar has ...".

Agreed.

> model I have is "y" is a label in some namespace x, and you have to (in
> some sense) look up where "y" should go regardless of whether you are
> setting the value or getting the value.
>
> Do you think this model is so far from the actual behaviour of Python that
> it is useless? Or is it fair to lump getting and setting attributes/names
> together?

I think it's reasonable: Python does first check if type(x).y is an
overriding descriptor (==one with a __set__ method), at least in the
mainstream case (oldstyle classic are weird;-).

> > and in "import x.y" it's
> > "bind x AND then bind y in namespace y".
>
> I assume that's a typo and you mean "bind y in namespace x".

Yep. Differently from the other bots (tim and /f), I'm programmed to
randomly make errors once in a while -- makes it easier to pass the
Turing test (many people mistakenly think I'm human, since "to err is
human", while nobody would think THAT of impeccabile timbot and effbot).

> But even "import x.y" is conceptually a lookup, equivalent to x.y =
> __import__("x.y"), with the understanding that x = __import__("x") is
> automagically run first.
>
> [hand-waving, hand-waving, hand-waving... of course imports do a lot more
> than just setting a name in a namespace]

Of course, but so do some other statements that ALSO bind a name (in the
current namespace only, in today's Python), such as class and def.
We're just focusing on the binding part;-).


> But in all three of:
>
> foo.bar = something
> something = foo.bar
> import foo.bar
>
> the hierarchy goes from left to right, with bar being "inside" foo, for
> some meaning of inside. The Original Poster's syntax would reverse that,
> with def foo.bar(x,y) creating parameter foo "inside" method bar.

True. Of course, the OP might argue that if x.f() can CALL f(x)
[placing x ``inside'' f], it's fair that a def of a composite name
should also ``swap insideness and outsideness'' similarly. But, as I
said, "I'm not supporting the OP's idea; just rejecting the specific
objections to it". For once, I have a hard time articulating exactly why
I'd dislike such semantics for hypothetic syntax "def x.y", besides
minor points such as the difficulties wrt generalizing to "def x.y.z"...
but I do know which objections are NOT the ones which make me feel such
dislike!-)


Alex

Alex Martelli

unread,
Feb 3, 2006, 11:28:41 PM2/3/06
to
Terry Reedy <tjr...@udel.edu> wrote:
...

> As was once pointed out to me some years ago, when I wrote something
> similar, a.f() is not just a shortcut for A.f(a) [a.__class__.f(a)]. The
> latter only looks for f in the class A namespace while the former also
> looks in superclass namespaces.

Nope:

>>> class B:
... def f(self): print 'b.f'
...
>>> class A(B): pass
...
>>> a=A()
>>> a.__class__.f(a)
b.f
>>>

Inheritance applies in any lookup of an attribute in a class, just as
well as on an instance of the class.

Alex

Alex Martelli

unread,
Feb 3, 2006, 11:28:40 PM2/3/06
to
<n.es...@gmx.de> wrote:
...

> your idea. Could you summarize how exactly "f(x,y=z)" should be
> resolved, i.e. where it should look for "f"?

Lexically: local scope, outer functions outwards, globals, builtins.


Alex

Message has been deleted

Donn Cave

unread,
Feb 4, 2006, 1:50:46 AM2/4/06
to
Quoth n.es...@gmx.de:

a.f ==> f(a)

I would agree that I didn't understand your answers, but they weren't
really answers so much as questions, along the lines of ``well then,
how would this work?'' I seem to have missed what you were driving at,
but maybe if you were to just came out and explain the point?

Of course the whole business is kind of a joke, since there is no way
anyone in their right mind would wish to change Python's notation for
such trivial reasons, but there actually are languages that resolve
functions based on argument types. Overloading in C++ is somewhat
like this, Haskell's typeclass mechanism, and there is a ``multiple
dispatch'' model that I have no experience with but is not without its
supporters.

Donn Cave, do...@drizzle.com

Terry Reedy

unread,
Feb 4, 2006, 3:15:24 AM2/4/06
to pytho...@python.org

"Jean-Paul Calderone" <exa...@divmod.com> wrote in message
news:20060203211426.2697.1835776858.divmod.quotient.6256@ohm...

> I'm not sure I follow. Surely you're not suggesting that this doesn't
> work:
>
> >>> class X:
> ... def foo(self):
> ... print 'X.foo', self
> ...
> >>> class A(X):
> ... pass
> ...
> >>> o = A()
> >>> A.foo(o)
> X.foo <__main__.A instance at 0xb7cab64c>
> >>>

Either things have changed or I was misinformed and neglected to verify ;-(

Jens Theisen

unread,
Feb 4, 2006, 6:03:00 AM2/4/06
to
n.estner wrote:

> Yes, I 100% agree to that point!
> But the point is, the current situation is not newbie-friendly (I can
> tell, I am a newbie): I declare a method with 3 parameters but when I
> call it I only pass 2 parameters. That's confusing. If I declare a
> member variable, I write: "self.x = ValueForX", why can't I be equally
> explicit for declaring member functions?

For someone new to OO in general it might as well be something good, so he
realises that there actually really is a hidden parameter. After all,
there is something to understand with "self", and this discrapency between
the number of arguments and parameters puts newbies to it.

Jens

n.es...@gmx.de

unread,
Feb 4, 2006, 9:37:46 AM2/4/06
to
Donn Cave wrote:

> Quoth n.es...@gmx.de:
> | > Still see no problem. Of course, it goes without saying that
> | > Python 2.4 doesn't work this way, but given that it's theoretically
> | > possible for f(a) to be resolved similarly to a.f, then I really
> | > do not see what you're seeing here. The kwargs parameter appears
> | > irrelevant from where I'm sitting.
> |
> | Then either you didn't understand my answers, or I didn't understand
> | your idea. Could you summarize how exactly "f(x,y=z)" should be
> | resolved, i.e. where it should look for "f"?
>
> a.f ==> f(a)

So, if the compiler recognizes the tokens "a.f", it should treat them
as if it found the tokens "f(a)". But that wouldn't do what you want.
You want it to do something different if it found the tokens "f(a)".

> I would agree that I didn't understand your answers, but they weren't
> really answers so much as questions, along the lines of ``well then,
> how would this work?'' I seem to have missed what you were driving at,
> but maybe if you were to just came out and explain the point?

You do know what a rethorical question is?

The first point is: Python has global functions, as well as methods. If
f(a) should look up f inside a first, that would shadow any global or
local f. That's bad, because python is dynamically typed, and you
sometimes down' know what "a" is. Things like "open(filename)" or
"tuple(a,b,c)" could behave completely unexpected, if "filename" had an
"open" or "a" a "tuple" attribute.

The other point is: Python supports named arguments. The algorithm to
put positional and named arguments into the right parameters is rather
tricky, and it _must_ know the function that's being called to work.
So, you simply can't make function lookup depend on the parameters,
it's a hen-egg problem.

> Of course the whole business is kind of a joke, since there is no way
> anyone in their right mind would wish to change Python's notation for
> such trivial reasons, but there actually are languages that resolve
> functions based on argument types. Overloading in C++ is somewhat
> like this, Haskell's typeclass mechanism, and there is a ``multiple
> dispatch'' model that I have no experience with but is not without its
> supporters.

Yes, but both C++ and Haskell are statically typed, and neither
supports named arguments.
(We're talking about one function operating on one object, so I don't
see what multiple dispatch has to do with this)

Donn Cave

unread,
Feb 4, 2006, 12:07:54 PM2/4/06
to
Quoth n.es...@gmx.de:
...

| The first point is: Python has global functions, as well as methods. If
| f(a) should look up f inside a first, that would shadow any global or
| local f. That's bad, because python is dynamically typed, and you
| sometimes down' know what "a" is. Things like "open(filename)" or
| "tuple(a,b,c)" could behave completely unexpected, if "filename" had an
| "open" or "a" a "tuple" attribute.

Well, of course we have to assume as part of the proposal that
it would documented and actually would be expected, to the extent
that one is entitled to expect anything in Python. It seems to
me that if you bring an even slightly open mind to the question,
when we apply "open" to an object that supports "open" with its
own function, what could be more appropriate than to call that
function? I will allow that there is some potential for problems
here, but there may be ways to finesse them. Haven't thought real
hard about it.

| The other point is: Python supports named arguments. The algorithm to
| put positional and named arguments into the right parameters is rather
| tricky, and it _must_ know the function that's being called to work.
| So, you simply can't make function lookup depend on the parameters,
| it's a hen-egg problem.

Ah. I see no reason this system needs to support a named first
parameter, though, so I suppose a function application like f(a=x,...)
would be exempt from parameter lookup. This seems like an implementation
detail.

| > Of course the whole business is kind of a joke, since there is no way
| > anyone in their right mind would wish to change Python's notation for
| > such trivial reasons, but there actually are languages that resolve
| > functions based on argument types. Overloading in C++ is somewhat
| > like this, Haskell's typeclass mechanism, and there is a ``multiple
| > dispatch'' model that I have no experience with but is not without its
| > supporters.
|
| Yes, but both C++ and Haskell are statically typed, and neither
| supports named arguments.
| (We're talking about one function operating on one object, so I don't
| see what multiple dispatch has to do with this)

Come on, you know that in the unlikely event this idea were to be seriously
considered, someone would be hot to extend it to multiple objects before
it even got implemented on one, but in any case, single dispatch sounds
like just a restricted case of multiple dispatch, so if the latter is
feasible, so is the former. I've heard talk about a form of static typing
for Python, and obviously that has the potential to considerably enhance
the possibilities in this area.

Donn Cave, do...@drizzle.com

Nick Craig-Wood

unread,
Feb 4, 2006, 12:30:04 PM2/4/06
to
Terry Hancock <han...@anansispaceworks.com> wrote:
> On Thu, 02 Feb 2006 19:27:55 -0600
> DH <n...@spam.com> wrote:
> > But I think most people who don't like the extraneous
> > 'self' in python just consider it a minor inconvenience
> > and don't even notice it after using python for a while.
>
> After messing around with Javascript (many magical
> variables that suddenly show up in your namespaces!), I
> began to *seriously* appreciate Python's design. Having
> self as an explicit parameter is beautiful self-documenting
> design.

I have to agree...

Here is my experience with the same idea in C++...

I've converted lots of C code written in an object oriented style into
C++. In C you pass round a pointer to a struct, which gets
transformed into the new class on conversion. Typically the code is
then full of this->member = that, etc. This is the python equivalent
of self.member = that. At this point I usually remove all the this->
from the code which then causes it to malfunction horribly at run-time
(it compiles fine) because of all the name space clashes between the
things in the class and the local variables. The compiler doesn't
warn about this - its perfectly legal C++.

In a lot of big C++ programs various conventions are used to try to
help with this - naming all parameters to functions _name rather than
name, or using this->member rather than member. The python way of
enforcing self.member is much cleaner and never comes back to bite you!

--
Nick Craig-Wood <ni...@craig-wood.com> -- http://www.craig-wood.com/nick

Terry Hancock

unread,
Feb 5, 2006, 7:51:49 PM2/5/06
to pytho...@python.org
On 04 Feb 2006 11:03:00 +0000

Yes. I have to say that I learned OOP at the same time as
Python (I made attempts with C++ that were moderately
successful, but beyond implementing new math objects, I
couldn't really see the benefit OOP then. I didn't "get"
it until I started using Python).

So, the idea of "the object itself is the first argument to
the function" made it implicitly clear to me what the heck
was this whole business about "methods".

I found the Python approach is very enlightening.

By contrast, Javascript seems positively obtuse. First, the
equivalent to "self" is a magically-appearing variable
called "this". But to make matters worse, this behavior is
repeated in many places -- you have to know when and where
magical variables like "this" and "prototype" appear, and
it's not at all obvious when reading other people's code.

(I suppose a formal introduction to Javascript would
explain these things -- but I note that many online "how to"
type documents skip them, partly because OOP is not very
popular with most casual Javascripters).

I tend to think of Javascript as "almost Python, but
stupidly designed", because of stuff like this.

My apologies to Javascript fans, I acknowledge that my
opinion is subjective. ;-)

Cheers,
Terry

--
Terry Hancock (han...@AnansiSpaceworks.com)
Anansi Spaceworks http://www.AnansiSpaceworks.com

Frithiof Andreas Jensen

unread,
Feb 8, 2006, 8:03:04 AM2/8/06
to

<n.es...@gmx.de> wrote in message
news:1138918102.8...@o13g2000cwo.googlegroups.com...

> Having read previous discussions on python-dev I think I'm not the only
> Python programmer who doesn't particularly like python's "self"
> parameter:

Ok, there might be five programmers and one imam. The imam does not like
anything more recent than 700 A.D ...

> What do you think?
>

Troll!


DH

unread,
Feb 8, 2006, 8:26:09 AM2/8/06
to


You Danes and your Muslim jokes :)

Ben Wilson

unread,
Feb 8, 2006, 8:44:40 AM2/8/06
to
"But the point is, the current situation is not newbie-friendly (I can
tell, I am a newbie)"

I will agree to that, as I consider myself still new. _But_, it's a
stumbling stone only briefly. Get enough nagging error messages, and
you learn and move on. I agree with the grandparent poster that it is a
perfect self-documenting thing, as the use of 'self' is pretty obvious.
For a language that one can learn in a short time, this is a tempest in
a teacup.

I'm just trying to disown my several years of Perl. I like PHP too much
and have no experience with Python in a CGI environment. So, I'm a
little bit confused linguistically. ;-)

Charles Krug

unread,
Feb 8, 2006, 5:57:15 PM2/8/06
to
On 2006-02-08, Ben Wilson <dau...@gmail.com> wrote:
> "But the point is, the current situation is not newbie-friendly (I can
> tell, I am a newbie)"
>
> I will agree to that, as I consider myself still new. _But_, it's a
> stumbling stone only briefly. Get enough nagging error messages, and
> you learn and move on. I agree with the grandparent poster that it is a
> perfect self-documenting thing, as the use of 'self' is pretty obvious.
> For a language that one can learn in a short time, this is a tempest in
> a teacup.
>

This old C hound finds it much more sensible than C++ or Java, where the
"self" parameter (called "this") is implicit rather than explicit and
you just sorta kinda hafta "know" it's there and the correct syntax to
use to reference it.

Then there's all the places where you need a Secret Decoder Ring--in
Java you have to define the equivalents of stdout and stdin as they
aren't provided. In c++ you can't overload the << operator in your
class, you have to use a "friend" function and you have to return an
ostream--the "Rule of Three" for constructors, and just generally lots
of small knotty issues to bite beginners.

9 times out of 10, Python "Just Works" the first time and things do what
your mind says they "should" without having to learn a seventeen special
cases to everything.

IMO, YMMV, Not Valid in Vermont, Happy Fun Ball may accellerate to
dangerous speeds. Do NOT taunt Happy Fun Ball.


Frithiof Andreas Jensen

unread,
Feb 9, 2006, 4:35:37 AM2/9/06
to

"DH" <n...@spam.com> wrote in message
news:CdadnavYLe_...@comcast.com...

;-)

A culture thing, that: They are now accepted as part of society, so we treat
them equally to the people from Århus, Copenhagen, West-Jutland,
Sout-Jutland, Bornholm and Mols (a tiny area 30 km from Århus). If we did
not care for them, we would not poke fun at them occasionally.

So far, I think the "integration" has really improved a lot because this
affair has clearly shown that the Danish muslims are pretty much like
everyone else here. The ethnic kiosks still sell Jyllands Posten, the Danish
still buy groceries in ethnic shops e.t.c. Like Normal. No riots, looting
and threats from hooded cowards and bullies.


What we instead have learned are that the Imams - some of which have been
given asylum - are blatantly lying and falsifying evidence in order to
slander the country that pay their social security when the very first
opportunity arises. Maybe those people should not be here in the first
place.

We have also learned that there is no point in getting involved in dialogue,
export grants (i.e. bribes) and foreign aid money (more bribes) with
dictatorships and defunct states. The effort should be directed elsewhere,
where it is actually any use.

Finally we can take comfort in knowing that the "lunatic segment" in the
population is clearly less than 1500 out of 5,000,000 people - although the
loonies do get 80% of the media coverage (like f.ex. the 300 "autonomen"
that just *had* to be the only violent segment in a media-hyped
"confrontational" demo with 30(!) neo-nazis, 200 muslims and about half the
Danish police force present in riot gear - Great Plan Einstein; ). The
TeeVee news should be relabeled "Fools Hour" - their mantra seems to be that
"if you want the opinion of any large group, go seek out the village idiot
and ask him".

The conclusion is that the *real* threat to democracy does *not* come from
the lunatic segment but from connected people with nice suits and vested
interests such as the Danish Industri Association that are clearly willing
to take in a used Sharia as part of a trade. They worked for Hitler too and
has clearly learned nothing!!


PS:

If one was trying to detect fanatics of any creed, a certain indicator would
be that they have absolutely no sense of humour - they suffer from a
yet-to-be-described variant of autism I.M.O.


Christos Georgiou

unread,
Feb 14, 2006, 2:50:41 AM2/14/06
to
On Thu, 9 Feb 2006 10:35:37 +0100, rumours say that "Frithiof Andreas
Jensen" <frithiof.jensen@die_spammer_die.ericsson.com> might have written:

>If one was trying to detect fanatics of any creed, a certain indicator would
>be that they have absolutely no sense of humour - they suffer from a
>yet-to-be-described variant of autism I.M.O.

Although I generally agree, I've seen images of fanatics laughing madly when
they employ their fanatism; so they might have some sense of humour, even if
a perverted one (perverted relative to your or my sense of humour, obviously
:) They tend to lack self-sarcasm, though.

Anyway, someone wiser than me (probably so much wiser that I subconsciously
forgot their name!) said: "The difference between a saint and a fanatic is
that the saint fights the evil inside him/herself..."
--
TZOTZIOY, I speak England very best.
"Dear Paul,
please stop spamming us."
The Corinthians

0 new messages