Re: Getting rid of self.

2005-01-10 Thread Alex Martelli
BJörn Lindqvist [EMAIL PROTECTED] wrote:
   ...
  http://starship.python.net/crew/mwh/hacks/selfless.py
 
 That's excellent! There is one small problem with the code though:

It shows the fundamentals of how to rewrite the bytecode, yes.

 .class Hi(Selfless):
 .__attrs__ = [x]
 .def __init__(x):
 .self.x = x
 
 In this case, I think the Python interpreter should realise that the
 parameter x shadows the attribute x. But the selfless code has
 problems with that. I want it to work exactly like how the situation
 is handled in Java and C++.

I believe you're referring to the test in rewrite_method:

if op.arg  code.co_argcount:
raise ValueError, parameter also instance member!

If you think that parameters that are also instance members should
shadow instance members, just skip the op.arg cases which are less
than code.co_argcount -- those are the parameters.

  Alex Martelli:
  A decorator can entirely rewrite the bytecode (and more) of the method
  it's munging, so it can do essentially anything that is doable on the
  basis of information available at the time the decorator executes.
 
 Which I believe means that the instance variables have to be declared
 in the class? I am content with declaring them like the selfless
 approach does:

It means the information about which names are names of instance
attributes must be available somewhere, be that declared, inferred,
or whatever.  For example, many C++ shops have an ironclad rule that
instance attributes, and ONLY instance attributes, are always and
invariably named m_something.  If that's the rule you want to enforce,
then you don't necessarily need other declarations or inferences, but
rather can choose to infer the status of a name from looking at the name
itself, if you wish.  Declarations or other complications yet such as:

 alternative would be not to declare the variables in an __attr__ list,
 and instead let them be declared by having them initialised in the
 __init__. I.e:
 
 .def __init__(hi, foo):
 .self.hi = hi
 .self.foo = foo
 
 When the metaclass then does it magic, it would go through the code of
 the __init__ method, see the assignments to self.hi and self.foo,
 decide that hi and foo are attributes of the object and replace
 hi and foo in all other methods with self.hi and self.foo. The

OK, but this approach is not compatible with your stated desire, which I
re-quote...:

 I want it to work exactly like how the situation
 is handled in Java and C++.

...because for example it does not deal with any attributes which may be
initialized in a *superclass*'s __init__.  However, I guess it could be
extended at the cost of some further lack of transparency, to obtain
just as horrid a mess as you require, where it's impossible for any
human reader to guess whether, say,
hi = 33
is setting a local variable, or an instance variable, without chasing
down and studying the sources of an unbounded number of superclasses.

I do not think there is any _good_ solution (which is why many C++ shops
have that rule about spelling this m_hi if it's an instance variable,
keeping the spelling 'hi' for non-instance variables -- an attempt to
get SOME human readability back; a smaller but non-null number of such
shops even achieve the same purpose by mandating the use of 'this-hi'
-- just the Python rule you want to work around, essentially).  The
least bad might be to rely on __attrs__, enriching whatever is in the
current class's __attr__ with any __attrs__ that may be found in base
classes PLUS any member variables specifically set in __init__ -- if you
focus on convenience in writing the code, to the detriment of ability to
read and understand it; or else, for more readability, demand that
__attrs__ list everything (including explicitly attributes coming from
subclasses and ones set in any method by explicit self.whatever = ...)
and diagnose the problem, with at least a warning, if it doesn't.

Yes, there's redundancy in the second choice, but that's what
declarations are all about: if you want to introduce the equivalent of
declarations, don't be surprised if redundancy comes with them.

 downside is that it probably could never be foolproof against code
 like this:
 
 .def __init__(hi, foo):
 .if hi:
 .self.hi = hi
 .else:
 .self.foo = foo
 
 But AFAIK, that example is a corner case and you shouldn't write such
 code anyway. :)

I don't see any problem with this code.  A static analysis will show
that both hi and foo are local variables.  Either may be not
initialized, of course, but having to deal with variables which are not
initialized IS a common problem of C++: you said you want to do things
like in C++, so you should be happy to have this problem, too.


  Alex Martelli:
  You do, however, need to nail down the specs.  What your 'magic' does
  is roughly the equivalent of a from ... import * (except it
  ...
  Then, you must decide whether this applies to all names the method
  accesses 

Re: Getting rid of self.

2005-01-09 Thread Tim Roberts
BJörn Lindqvist [EMAIL PROTECTED] wrote:

I think it would be cool if you could refer to instance variables
without prefixing with self. I know noone else thinks like me so
Python will never be changed, but maybe you can already do it with
Python today?

.import sys
.
.def magic():
.s = 
.for var in sys._getframe(1).f_locals[self].__dict__:
.s += var +  = self. + var + \n
.return s
.
.class A:
.def __init__(self):
.self.hi = yo
.
.def meth(self):
.exec(magic())
.print hi
.
.a = A()
.a.meth()

It works! exec(magic()) does the needed hi = self.hi. 

Does it?

class A:
   def __init__(self):
   self.hi = yo

   def meth(self):
   exec(magic())
   print hi
   hi = baby
   print hi

   def other(self):
   exec(magic())
   print hi

a = A()
a.meth()
a.other()

That's way too fragile to be useful.
-- 
- Tim Roberts, [EMAIL PROTECTED]
  Providenza  Boekelheide, Inc.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Getting rid of self.

2005-01-09 Thread John Roth
Alex Martelli [EMAIL PROTECTED] wrote in message 
news:[EMAIL PROTECTED]
BJörn Lindqvist [EMAIL PROTECTED] wrote:
I think it would be cool if you could refer to instance variables
without prefixing with self. I know noone else thinks like me so
Some do -- Kent Beck's excellent book on TDD-by-example has a specific
grouse against that in the chapter where he develops the unittest module
(in Python).  But that's how comes Kent is a _Smalltalk_ programmer
rather than a _Python_ programmer, see?-)
And of course, the reason it's possible in Smalltalk but not in Python
is that Smalltalk requires the declaration of instance variables. Also
Smalltalk does not have things like module variables and builtins.
The interpreter knows exactly what every name references, which
isn't true in Python.
John Roth

Alex 
--
http://mail.python.org/mailman/listinfo/python-list


Re: Getting rid of self.

2005-01-09 Thread BJörn Lindqvist
Thank you for your replies. It is very nice to see that a thread you
started is generating so much discussion, but please, I have read the
previous debates so I know all about what people think about self.
Spare the you shouldn't do that and self is here to stay replies
to the threads in which people are actually suggesting changing the
syntax. :)

I know the solution I presented is not working ideally, because you
have to use self to assign to instance attributes like self.hi =
'baby'.

 Sean Ross:
 http://starship.python.net/crew/mwh/hacks/selfless.py

That's excellent! There is one small problem with the code though:

.class Hi(Selfless):
.__attrs__ = [x]
.def __init__(x):
.self.x = x

In this case, I think the Python interpreter should realise that the
parameter x shadows the attribute x. But the selfless code has
problems with that. I want it to work exactly like how the situation
is handled in Java and C++.

 Alex Martelli:
 Björn Lindqvist:
 I think it would be cool if you could refer to instance variables
 without prefixing with self. I know noone else thinks like me so
 Some do -- Kent Beck's excellent book on TDD-by-example has a specific
 grouse against that in the chapter where he develops the unittest module

I have to get myself that book. 

 Alex Martelli:
 A decorator can entirely rewrite the bytecode (and more) of the method
 it's munging, so it can do essentially anything that is doable on the
 basis of information available at the time the decorator executes.

Which I believe means that the instance variables have to be declared
in the class? I am content with declaring them like the selfless
approach does:

__attrs__ = [hi, foo]

It's not optimal because it would lead to some name duplication when
a class is __init__:ed.

.__attrs__ = [hi, foo]
.def __init__(_hi, _foo):
.hi = _hi
.foo = _foo

I guess you can solve that adequately by using one of the recipes from
the Cookbook that automagically initialises an objects variable
depending on which variables was passed in the parameter list. Another
alternative would be not to declare the variables in an __attr__ list,
and instead let them be declared by having them initialised in the
__init__. I.e:

.def __init__(hi, foo):
.self.hi = hi
.self.foo = foo

When the metaclass then does it magic, it would go through the code of
the __init__ method, see the assignments to self.hi and self.foo,
decide that hi and foo are attributes of the object and replace
hi and foo in all other methods with self.hi and self.foo. The
downside is that it probably could never be foolproof against code
like this:

.def __init__(hi, foo):
.if hi:
.self.hi = hi
.else:
.self.foo = foo

But AFAIK, that example is a corner case and you shouldn't write such
code anyway. :)

 Alex Martelli:
 You do, however, need to nail down the specs.  What your 'magic' does
 is roughly the equivalent of a from ... import * (except it
 ...
 Then, you must decide whether this applies to all names the method
 accesses (which aren't already local).  For example, if the method
 has a statement such as: 
   x = len(y)

All names should be checked like this:
1. Is the name in the parameter list? If so, do not rebind it.
2. Is the name in the objects attribute list? If so, prepend self.
3. Do stuff like normal.

Example:

.class Foo(Selfless):
.def __init__(x):
.print x
.self.x = x*2
.def meth():
.x = x + 10
.print x
.def meth2(x):
.print x
.print self.x
.self.x = x
.
.o = Foo(50)
.print o.x
.o.meth()
.o.meth2(12)
.print o.x

Outputs:
50
100
110
12
110
12

 Alex Martelli:
 If you can give totally complete specifications, I can tell you
 whether your specs are doable (by a decorator, or other means), how,
 and at what cost.  Without knowing your specs, I can't tell; I can
 _guess_ that the answer is probably doable (as long as you're not
 demanding the code in the decorator to be an oracle for the future,

This is promising, I'm content with whatever slowdowns necessary as
long as I can prove those who say you can't do it wrong. :) It seems
to me that it should be doable by having the metaclass that modifies
the class go through the class and bytecode-rewrite all its methods.
So there has to be a big slowdown when the class is created, but after
that, it should execute at pure Python speed? That doesn't seem to
hard, and pretty robust too since bytecode doesn't change so often.
And THEN I'll rewrite python-mode so that it syntax highlights member
attributes! It will be cool.

-- 
mvh Björn
--
http://mail.python.org/mailman/listinfo/python-list


Re: Getting rid of self.

2005-01-09 Thread Jeremy Bowers
On Mon, 10 Jan 2005 01:51:07 +0100, BJrn Lindqvist wrote:
 This is promising, I'm content with whatever slowdowns necessary as long
 as I can prove those who say you can't do it wrong. :)

Since I think I'm the only person in this discussion that said anything
about what you can't do, be clear on what I said. You can't have both of
undeclared attributes on self and no use of self, in particular to add
new attributes. 

This is, if you take the time to understand what I mean, trivially true;
*somewhere* you need to declare whether a var is local to the function or
an instance member. For me, I prefer the explicit self and getting rid
of self now leaves you with the need to declare member variables
*somehow*, which I don't consider progress. But no matter what other magic
Alex works, you're only going to get one or the other; it's impossible for
the compiler to divine what you mean otherwise.

My point here isn't that you can't hack together code to do something
like what you want, and it is certainly a valid exercise in plumbing the
depths of Python and learning. My point is that you'll have to pay a price
in other ways. You can't make self go away for free. And that can't I
do mean.

(You weren't necessarily claiming you could. But I thought it still worth
saying; even if you weren't trying to remove self for free, others
certainly would mean it.)

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Getting rid of self.

2005-01-08 Thread Terry Reedy

BJörn Lindqvist [EMAIL PROTECTED] wrote in message 
news:[EMAIL PROTECTED]
I think it would be cool if you could refer to instance variables
without prefixing with self.

Others have expressed such a wish -- this comes up perhaps once a year. 
The bottom line is that as long as Python has separate instance and local 
namespaces with possibly duplicate names, then there must be a way to tell 
which namespace a name should be looked up in.  The current system is 
completely consistent with Python's object.attribute system.  It would be 
odd if instance attributes were referred to differently in module level 
code and function level code.

Terry J. Reedy



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Getting rid of self.

2005-01-07 Thread Bruno Desthuilliers
BJörn Lindqvist a écrit :
I think it would be cool if you could refer to instance variables
without prefixing with self. I know noone else thinks like me so
Python will never be changed, but maybe you can already do it with
Python today?
(snip code)
It works! exec(magic()) does the needed hi = self.hi. Not so
impressive in this case but much cooler when there is more instance
variables around. But the solution is very ugly because you have to
write exec(magic()) in every method. So I'm asking here if someone
knows a better way, maybe using decorators or metaclasses or other
black magic?
The better way is definitively to forget about black magic and 
understand why mandatory 'self' is Good Thing (tm).

(Tip : even when [this|self|@|whatsoever] is not mandatory, using it 
makes for much more readable code.)

Bruno
--
http://mail.python.org/mailman/listinfo/python-list


Re: Getting rid of self.

2005-01-07 Thread Luis M. Gonzalez
You can do it easier now without any black magic:

class c:
def __init__(s):
s.x = 1
s.y = 2
s.hi = Hi there!

The word self is not mandatory. You can type anything you want
instead of self, as long as you supply a keyword in its place (it can
be self, s or whatever you want).

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Getting rid of self.

2005-01-07 Thread Simon Brunning
On 7 Jan 2005 08:10:14 -0800, Luis M. Gonzalez [EMAIL PROTECTED] wrote:
 The word self is not mandatory. You can type anything you want
 instead of self, as long as you supply a keyword in its place (it can
 be self, s or whatever you want).

You *can*, yes, but please don't, not if there's any chance that
anyone other than you are going to have to look at your code.
'self.whatever' is clearly an instance attribute. 's.whatever' isn't
clearly anything - the reader will have to go off and work out what
the 's' object is.

The self prefix is a perfectly good convention. Let's stick to it.

-- 
Cheers,
Simon B,
[EMAIL PROTECTED],
http://www.brunningonline.net/simon/blog/
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Getting rid of self.

2005-01-07 Thread Roy Smith
Simon Brunning  [EMAIL PROTECTED] wrote:
On 7 Jan 2005 08:10:14 -0800, Luis M. Gonzalez [EMAIL PROTECTED] wrote:
 The word self is not mandatory. You can type anything you want
 instead of self, as long as you supply a keyword in its place (it can
 be self, s or whatever you want).

You *can*, yes, but please don't, not if there's any chance that
anyone other than you are going to have to look at your code.
'self.whatever' is clearly an instance attribute. 's.whatever' isn't
clearly anything - the reader will have to go off and work out what
the 's' object is.

+1.

If there is one coding convention which is constant through the Python
world, it's that the first argument to a class method is named
self.  Using anything else, while legal, is just being different for
the sake of being different.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Getting rid of self.

2005-01-07 Thread John Roth

BJörn Lindqvist [EMAIL PROTECTED] wrote in message 
news:[EMAIL PROTECTED]
I think it would be cool if you could refer to instance variables
without prefixing with self. I know noone else thinks like me so
Python will never be changed, but maybe you can already do it with
Python today?

...
It works! exec(magic()) does the needed hi = self.hi. Not so
impressive in this case but much cooler when there is more instance
variables around. But the solution is very ugly because you have to
write exec(magic()) in every method. So I'm asking here if someone
knows a better way, maybe using decorators or metaclasses or other
black magic?
[response]
Having to specify the instance explicitly is something that
Python needs because it isn't a statically typed language.
In a statically typed language, all variables are pre-declared,
so the compiler knows where they all are.
Python's compiler knows about local variables. It
doesn't know where any other variables are, so it
has to search. Including the instance as one of the
method parameters means that the search splits
right at the front: either it starts looking up the
instance, or it goes up the definition chain (usually
empty) to the module namespace and then the
builtins.
Eliminating self would mean it would have to
either search the instance before the module and
builtins, or search the module and builtins before
the instance. This is both a performance issue
and a maintenance issue because of the increased
possibility of one shadowing the other.
This is distinct from the issue of how to spell
self. As another responder has already said,
you can spell it any way you want; it's simply
whatever you choose to call the first paramteter
to the method.
Going the other way, the word self could become
a keyword, removing the necessity of specifying it
among the method parameters. While I like the idea,
there's enough dislike of the notion that it's not going
to happen.
John Roth
--
mvh Björn 

--
http://mail.python.org/mailman/listinfo/python-list


Re: Getting rid of self.

2005-01-07 Thread Michael Hobbs
Nick Coghlan [EMAIL PROTECTED] wrote:
 
 Wait for Python 3k when this will work:
 
 class c:
   def __init__(self):
 with self:
   .x = 1
   .y = 2
   .hi = Hi there!

Python is looking more like JavaScript every day...

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Getting rid of self.

2005-01-07 Thread BJörn Lindqvist
Thank you for your replies. But they don't deal with my original
question. :) I have read the thousands of posts all saying self is
good and they are right. But this time I want to be different m-kay?
I figure that there might be some way to solve my problem by doing
this:

.def instancevar2locals(method):
.# Do something magic here so that exec(magic()) is automagically
run each time
.# the function is invoked.
.newmethod = method
.return newmethod

And then in the class definition something like this:

.class A:
.def __init__(self):
.self.hi = hi
.def meth(self):
.print hi
.meth = instancevar2locals(meth)

But beyond that, I have no idea and I would be grateful if someone
would like to help me with it.
-- 
mvh Björn
--
http://mail.python.org/mailman/listinfo/python-list


Re: Getting rid of self.

2005-01-07 Thread John Roth
Roy Smith [EMAIL PROTECTED] wrote in message 
news:[EMAIL PROTECTED]
Simon Brunning  [EMAIL PROTECTED] wrote:
On 7 Jan 2005 08:10:14 -0800, Luis M. Gonzalez [EMAIL PROTECTED] wrote:
The word self is not mandatory. You can type anything you want
instead of self, as long as you supply a keyword in its place (it can
be self, s or whatever you want).
You *can*, yes, but please don't, not if there's any chance that
anyone other than you are going to have to look at your code.
'self.whatever' is clearly an instance attribute. 's.whatever' isn't
clearly anything - the reader will have to go off and work out what
the 's' object is.
+1.
If there is one coding convention which is constant through the Python
world, it's that the first argument to a class method is named
self.  Using anything else, while legal, is just being different for
the sake of being different.
Didn't you mean instance method? Class methods are a different
beast, and the few examples I've seen seem to use the word klas.
John Roth 

--
http://mail.python.org/mailman/listinfo/python-list


Re: Getting rid of self.

2005-01-07 Thread Roy Smith
In article [EMAIL PROTECTED],
John Roth [EMAIL PROTECTED] wrote:

Roy Smith [EMAIL PROTECTED] wrote in message 
news:[EMAIL PROTECTED]
 Simon Brunning  [EMAIL PROTECTED] wrote:
On 7 Jan 2005 08:10:14 -0800, Luis M. Gonzalez [EMAIL PROTECTED] wrote:
 The word self is not mandatory. You can type anything you want
 instead of self, as long as you supply a keyword in its place (it can
 be self, s or whatever you want).

You *can*, yes, but please don't, not if there's any chance that
anyone other than you are going to have to look at your code.
'self.whatever' is clearly an instance attribute. 's.whatever' isn't
clearly anything - the reader will have to go off and work out what
the 's' object is.

 +1.

 If there is one coding convention which is constant through the Python
 world, it's that the first argument to a class method is named
 self.  Using anything else, while legal, is just being different for
 the sake of being different.

Didn't you mean instance method? Class methods are a different
beast, and the few examples I've seen seem to use the word klas.

Sorry, yes.  My bad.

I used to work with a C++ guy who always used class when he should
have used instance.  It drove me crazy. :-)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Getting rid of self.

2005-01-07 Thread Sean Ross
BJörn Lindqvist [EMAIL PROTECTED] wrote in message
news:[EMAIL PROTECTED]
Thank you for your replies. But they don't deal with my original
question. :) I have read the thousands of posts all saying self is
good and they are right. But this time I want to be different m-kay?
I figure that there might be some way to solve my problem by doing
this:
[snip ...]
But beyond that, I have no idea and I would be grateful if someone
would like to help me with it.


http://starship.python.net/crew/mwh/hacks/selfless.py


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Getting rid of self.

2005-01-07 Thread Jeremy Bowers
On Fri, 07 Jan 2005 14:39:09 +0100, BJrn Lindqvist wrote:
 It works! exec(magic()) does the needed hi = self.hi.

No it doesn't. Try hi = 'newValue' and see what happens.

So the next step is to write an unmagic function. So now how do you add
instance variables?

There is no way to avoid self *and* not pre-declare variables in some
fashion as belonging to the instance (as declarations, as sigils, what
have you). Given that Python is not, will not, and should not do the
latter, I submit that self is, at least for you, the lesser of two
evils. (I don't consider it evil at all, so it isn't such for me; were I
programming in C++ routinely now I'd prefix this and dispense with that
ugly m_ garbage. (One of the things I ***hate*** about C++ culture is
its acceptance of hideously ugly variable names, but now I'm two
parentheticals deep so I probably ought to stop.))
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Getting rid of self.

2005-01-07 Thread Roy Smith
Jeremy Bowers [EMAIL PROTECTED] wrote:
 were I programming in C++ routinely now I'd prefix this and 
 dispense with that ugly m_ garbage. (One of the things I ***hate*** 
 about C++ culture is its acceptance of hideously ugly variable names, 
 but now I'm two parentheticals deep so I probably ought to stop.))

I'm currently working in a C++ system where they have a wrapper class 
that provides some transaction locking functionality for member access.  
The colloquial name for the wrapped this pointer is self, i.e. they do 
self = wrapper (this) at the beginning of functions that need it.  You 
can then do member to get the bare access or self.member to get the 
locking functionality.

It's actually kind of neat, but boy does it play headgames with me when 
I switch back and forth between that and Python.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Getting rid of self.

2005-01-07 Thread Nick Coghlan
Roy Smith wrote:
It's actually kind of neat, but boy does it play headgames with me when 
I switch back and forth between that and Python.
Switching back and forth betwen C++ and Python plays headgames *anyway* }:
Cheers,
Nick.
Hardware control with Python is nice. . .
--
Nick Coghlan   |   [EMAIL PROTECTED]   |   Brisbane, Australia
---
http://boredomandlaziness.skystorm.net
--
http://mail.python.org/mailman/listinfo/python-list