473,836 Members | 1,487 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

the annoying, verbose self

Is there any trick to get rid of having to type the annoying,
character-eating "self." prefix everywhere in a class? Sometimes I
avoid OO just not to deal with its verbosity. In fact, I try to use
Ruby anywhere speed is not crucial especially for @ prefix is better-
looking than self.

But things grow -- is there any metaprogramming tricks or whatnot we
can throw on the self?

Cheers,
Alexy
Nov 21 '07
84 7240
Ton van Vliet <sh***********@ green.meadowwro te:
It would boil down to choice: explicit/speed vs implicit/readability
No, it would boil down to explicit+speed+ readability+mai ntainability vs
implicit+error prone.

It would mean that as well as the interpreter having to search the
instance to work out whether each name referenced an attribute or a global
the reader would also have to perform the same search. It would mean that
adding a new attribute to an instance would change the meaning of the
methods which is a recipe for disaster.

Nov 24 '07 #41
On Nov 24, 7:50 am, Marc 'BlackJack' Rintsch <bj_...@gmx.net wrote:
On Sat, 24 Nov 2007 02:54:27 -0800, samwyse wrote:
On Nov 24, 4:07 am, Marc 'BlackJack' Rintsch <bj_...@gmx.net wrote:
On Sat, 24 Nov 2007 01:55:38 -0800, samwyse wrote:
I've had the same thought, along with another. You see, on of my pet
peeves about all OO languages that that when creating new code, I
generally begin by writing something like this:
cat = 'felix'
dog = 'rover'
def example():
global cat, dog # not always required, but frequently needed
return ', '.join((cat, dog))
Ouch that's bad design IMHO. The need to use ``global`` is a design
smell, if needed *frequently* it starts to stink.
I'm not sure what you mean. In the example that I gave, the 'global'
statement isn't needed. However, here's a different example:

I mean that global names that are (re)bound from within functions couple
these functions in a non-obvious way and make the code and data flow harder
to follow and understand. Also it makes refactoring and testing more
difficult because of the dependencies.
The whole point of this sub-thread is the difficulty of turning global
vars and functions into class vars and functions, and that is
something that is usually done precisely because the code and data
flow has become harder to follow and understand.
Nov 24 '07 #42
On Sat, 24 Nov 2007 08:27:56 -0800, samwyse wrote:
On Nov 24, 7:50 am, Marc 'BlackJack' Rintsch <bj_...@gmx.net wrote:
>On Sat, 24 Nov 2007 02:54:27 -0800, samwyse wrote:
On Nov 24, 4:07 am, Marc 'BlackJack' Rintsch <bj_...@gmx.net wrote:
On Sat, 24 Nov 2007 01:55:38 -0800, samwyse wrote:
I've had the same thought, along with another. You see, on of my pet
peeves about all OO languages that that when creating new code, I
generally begin by writing something like this:
cat = 'felix'
dog = 'rover'
def example():
global cat, dog # not always required, but frequently needed
return ', '.join((cat, dog))
>Ouch that's bad design IMHO. The need to use ``global`` is a design
smell, if needed *frequently* it starts to stink.
I'm not sure what you mean. In the example that I gave, the 'global'
statement isn't needed. However, here's a different example:

I mean that global names that are (re)bound from within functions couple
these functions in a non-obvious way and make the code and data flow harder
to follow and understand. Also it makes refactoring and testing more
difficult because of the dependencies.

The whole point of this sub-thread is the difficulty of turning global
vars and functions into class vars and functions, and that is
something that is usually done precisely because the code and data
flow has become harder to follow and understand.
Then don't use "global variables". If you don't put anything except
constants, classes and functions in the module's namespace there's no
problem "lifting" them into a class later.

Ciao,
Marc 'BlackJack' Rintsch
Nov 24 '07 #43
On Nov 24, 10:07 am, Duncan Booth <duncan.bo...@i nvalid.invalid>
wrote:
Ton van Vliet <sheep.in.h...@ green.meadowwro te:
It would boil down to choice: explicit/speed vs implicit/readability

No, it would boil down to explicit+speed+ readability+mai ntainability vs
implicit+error prone.

It would mean that as well as the interpreter having to search the
instance to work out whether each name referenced an attribute or a global
the reader would also have to perform the same search. It would mean that
adding a new attribute to an instance would change the meaning of the
methods which is a recipe for disaster.
Besides Pascal, Visual Basic also offers a 'with' statement that
behaves almost in this way. That in itself should be an indication
that the whole thing is a bad idea. ;-)

The way it works, however, is that you do have to prefix members with
a '.' and the interpreter tries to bind with each nested 'with'
variable in turn. It's tolerable with one 'with' statment, but once
you start nesting them it becomes dangerous.

My idea in a parallel thread is to treat a '.' prefix like '../' in
file paths; each one moves you up a level in the symbol table. In a
top-level function, it means a global name; in a class method it means
a member. The @classmethod and @staticmethod decorators would need to
fix things so that '.' refers to the appropriate things. There's no
reason why a 'using' statement couldn't perform nesting as well: '.'
refers to the 'using' variable, '..' refers to what '.' previously
referred to, etc.

OTOH, the point of 'using' is to reduce typing, so you might instead
add 'as' clauses as an alternate way to reduce confusion:
>>using myclass.new() as p:
p.do_something( )
p.something_els e()

Of course, now its starting to look more like a Python 'with'
statement, and I think there's a way to do basically this already.
Nov 24 '07 #44
On 24 Nov 2007 16:07:18 GMT, Duncan Booth
<du**********@i nvalid.invalidw rote:
>Ton van Vliet <sh***********@ green.meadowwro te:
>It would boil down to choice: explicit/speed vs implicit/readability

No, it would boil down to explicit+speed+ readability+mai ntainability vs
implicit+err or prone.
It would not be a full fledged *implicit*, but only used in small
areas where many self's are coming together, and possibly clutter
readability (a subjective classification anyhow) and even could
degrade (code) maintainability .
>It would mean that as well as the interpreter having to search the
instance to work out whether each name referenced an attribute or a global
the reader would also have to perform the same search.
IMHO if it is limited to small overviewable sections I think it could
make life of the reader/coder/maintainer even easier and less error
prone.

I cannot judge for the interpreter part (*if* at all doable, it would
probably be the coder's choice between speed and readability)
>It would mean that adding a new attribute to an instance would change
the meaning of the methods which is a recipe for disaster.
I don't see what you have in mind here?

As stated some message levels back: 'bear with me', I'm not an expert,
just a beginning user ;-)

I have no problems with the explicit self at all, but just brought up
Pascal's 'with' statement, invented to improve readability only (and
saving some typing as well) and 'transposed' it to python, just as my
2 cents.

I don't want to defend or formally propose an implementation, just
giving comments where *I* do not fully understand the counter
arguments.

So let's not 'beat it to death', ok ;-)

--
Ton
Nov 24 '07 #45
On 24 Nov 2007 13:56:37 GMT, Marc 'BlackJack' Rintsch <bj****@gmx.net wrote:
So::

def meth(self):
using self:
tmp = raw_input('Ente r age: ')
age = int(tmp)

becomes::

def meth(self):
using self:
self.tmp = self.raw_input( 'Enter age: ')
self.age = self.int(tmp)

Binding `tmp` unnecessarily to the object and trying to get `raw_input()`
and `int()` from the object. Ouch. :-)
Yes, that's no good. So you would write it like so:

def meth(self,*args ):
tmp = int(raw_input(' Enter age:'))
using self:
age = tmp

Still an unnecessary lookup on tmp though :) And it would be useless
to use it for one assignment, the idea is to eliminate all the typing
with this:

self.var1 = 5
self.var2 = "a value"
self.var3 = stuff
self.var4 = [2,54,7,7]
self.var5 = "dingaling"
self.var6 = 6.4
self.var7 = 1
self.var8 = False
self.var9 = True

Of course that "self.var3 = stuff" under the using would result in a
bad lookup for "stuff", but the programmer who wanted to use this
would have to realize this and try to avoid it.

I have been known from time to time, for long assignments such as
this, to turn a string with keys and values into a dictionary, and
then update __dict__ with that dictionary, hehe. "var1,5;var 2,"a
value";var3,stu ff" Not the best practice but the fastest to type.
Sometimes I actually use a dictionary, but typing all of the quotes
for the keys gets old.

If there were a "using" or if the with statement would handle
something like this, I wouldn't use it. "s." is only 2 characters. I
saw chained dots mentioned. Chained dots are 2 characters. Why are
we still discussing this? "s." is the answer, or pulling the
attributes into local vars if you are going to use them many times, to
save lookup. This is not a band-aid, this is an actual valid
programming technique. There is more to programming than typing...

Self is never going away, most python programmers generally like or
aren't bothered by it, if you are new to the language try to get used
to it, if it's too bothersome you can use one of the hacks or try
other languages. I don't mean to be snobby either, one language does
not fit all.
Nov 24 '07 #46
On 24 Nov, 20:10, "Patrick Mullen" <saluk64...@gma il.comwrote:
>
Yes, that's no good. So you would write it like so:

def meth(self,*args ):
tmp = int(raw_input(' Enter age:'))
using self:
age = tmp

Still an unnecessary lookup on tmp though :)
Indeed. As has been mentioned, it's all about resolving names and how
much of that work gets done at run-time (and whether the magic
confuses the human reader further).
And it would be useless
to use it for one assignment, the idea is to eliminate all the typing
with this:

self.var1 = 5
self.var2 = "a value"
self.var3 = stuff
self.var4 = [2,54,7,7]
self.var5 = "dingaling"
self.var6 = 6.4
self.var7 = 1
self.var8 = False
self.var9 = True

Of course that "self.var3 = stuff" under the using would result in a
bad lookup for "stuff", but the programmer who wanted to use this
would have to realize this and try to avoid it.
I think the remedy is worse than the ailment, especially since the
Pascal "with" construct can make use of declared information about
structure attributes, while the absence of such declarations leaves
more work to be done in Python (and more detective work for future
maintainers of code). Of course, for cases like the above, assuming
that one doesn't feel that lists or dictionaries are acceptable
alternatives to large numbers of instance attributes (which might not
have such regular naming), one might suggest a useful extension of the
attribute access syntax. Taking part of the above example and
rewriting...

self.(var1, var2, var3, var4) = 5, "a value", stuff, [2,54,7,7]

I'm sure Mr Schluehr can provide a working demonstration of this with
very little effort. ;-)

Paul

P.S. There were some proposals for generalisations of the attribute
access mechanisms using not completely different syntax, but I don't
recall them addressing the issue of accessing multiple attributes at
the same time, and the use of arbitrary expressions in place of the
attribute name (where a tuple is used above) gave a distinct feeling
of writing something similar to a combination of the worst aspects of
some shell language with some of the nastier parts of microcomputer
assembly language. Let us, therefore, not get too enthusiastic about
such ideas!
Nov 24 '07 #47
samwyse wrote:
so you might instead
add 'as' clauses as an alternate way to reduce confusion:
>>>>using myclass.new() as p:

p.do_something( )
p.something_els e()
or even

p = myclass.new()
p.do_something( )
p.something_els e()

Doesn't even need any new syntax. :-)

--
Greg
Nov 24 '07 #48
Patrick Mullen wrote:
Sometimes I actually use a dictionary, but typing all of the quotes
for the keys gets old.
If the keys are all identifiers, you can use keyword
args to the dict constructor. So you could write

self.__dict__.u pdate(dict(var1 = 5,
var2 = "a value", var3 = stuff))

if you really wanted to. (Don't be surprised if
everyone else refuses to maintain your code, though!)

--
Greg
Nov 24 '07 #49
samwyse wrote:
Later, I inevitably decide to encapsulate it inside a class, which
means lots of source changes to change my function into a method
You'd be better off changing your design habits to make
things into classes from the beginning if you suspect
you may want it that way later.

--
Greg
Nov 24 '07 #50

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

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.