473,425 Members | 1,806 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,425 software developers and data experts.

Another try at Python's selfishness

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?

Feb 2 '06 #1
45 1599
In article <11**********************@o13g2000cwo.googlegroups .com>,
n.******@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:

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?


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
Feb 2 '06 #2
<n.******@gmx.de> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.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__

Feb 3 '06 #3
> 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.

Feb 3 '06 #4
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...

Feb 3 '06 #5
DH
n.******@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:

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'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.
Feb 3 '06 #6
In article <11**********************@z14g2000cwz.googlegroups .com>,
n.******@gmx.de wrote:
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())


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
Feb 3 '06 #7
<n.******@gmx.de> wrote in message
news:11*********************@g44g2000cwa.googlegro ups.com...
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...

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>

Feb 3 '06 #8
On Thu, 02 Feb 2006 19:27:55 -0600
DH <no@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 (ha*****@AnansiSpaceworks.com)
Anansi Spaceworks http://www.AnansiSpaceworks.com

Feb 3 '06 #9
n.******@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.
Feb 3 '06 #10
> 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.

Feb 3 '06 #11
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...

Feb 3 '06 #12
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.

Feb 3 '06 #13
> 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.

Feb 3 '06 #14
> 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?

Feb 3 '06 #15
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.

Feb 3 '06 #16
> 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.

Feb 3 '06 #17
Op 2006-02-03, n.******@gmx.de schreef <n.******@gmx.de>:
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)


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
Feb 3 '06 #18
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.

Feb 3 '06 #19
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.

Feb 3 '06 #20
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.

Feb 3 '06 #21

n.******@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

Feb 3 '06 #22
Op 2006-02-03, Ben Sizer schreef <ky*****@gmail.com>:

n.******@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
Feb 3 '06 #23
n.******@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 'o****@xiludom.gro'.split('@')])"
Feb 3 '06 #24
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
Feb 3 '06 #25
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
Feb 3 '06 #26
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.

Feb 3 '06 #27
> ...
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?

Feb 3 '06 #28
In article <11*********************@o13g2000cwo.googlegroups. com>,
n.******@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
Feb 3 '06 #29

"Magnus Lycka" <ly***@carmen.se> wrote in message
news:dr**********@wake.carmen.se...
n.******@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

Feb 3 '06 #30
> 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"?

Feb 3 '06 #31
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
Feb 4 '06 #32
<n.******@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
Feb 4 '06 #33
Terry Reedy <tj*****@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
Feb 4 '06 #34
Quoth n.******@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)

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
Feb 4 '06 #35
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

Feb 4 '06 #36
Donn Cave wrote:
Quoth n.******@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)

Feb 4 '06 #37
Quoth n.******@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
Feb 4 '06 #38
Terry Hancock <ha*****@anansispaceworks.com> wrote:
On Thu, 02 Feb 2006 19:27:55 -0600
DH <no@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
Feb 4 '06 #39
On 04 Feb 2006 11:03:00 +0000
jt***@arcor.de (Jens Theisen) wrote:
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.


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 (ha*****@AnansiSpaceworks.com)
Anansi Spaceworks http://www.AnansiSpaceworks.com

Feb 6 '06 #40

<n.******@gmx.de> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.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!
Feb 8 '06 #41
DH
Frithiof Andreas Jensen wrote:
<n.******@gmx.de> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.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 ...

You Danes and your Muslim jokes :)
Feb 8 '06 #42
"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. ;-)

Feb 8 '06 #43
On 2006-02-08, Ben Wilson <da****@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.
Feb 8 '06 #44

"DH" <no@spam.com> wrote in message
news:Cd********************@comcast.com...
Frithiof Andreas Jensen wrote:
<n.******@gmx.de> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.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 ...

You Danes and your Muslim jokes :)


;-)

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.
Feb 9 '06 #45
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
Feb 14 '06 #46

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Tubby Tudor | last post by:
What is the best way to call one python script from within another python script? For example: one.py finishes succesfully and calls two.py which finishes OK and then calls three.py Thanks...
0
by: Anand K Rayudu | last post by:
Hi I have extended/embedded python into my application, it is working great, The documentation is too good, I could replace existing scripting tool to python in no time. I have one problem...
8
by: Paul Cochrane | last post by:
Hi all, I've got an application that I'm writing that autogenerates python code which I then execute with exec(). I know that this is not the best way to run things, and I'm not 100% sure as to...
9
by: cgwalters | last post by:
Hi, I've recently been working on an application which does quite a bit of searching through large data structures and string matching, and I was thinking that it would help to put some of this...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.