the annoying, verbose self

S

samwyse

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...

Actually, the chained dots are solving a completely different problem,
that of refactoring a collection of functions that use global vars
into a class.

Although I'm now wondering if I could jigger something together using
globals() to make a top-level self-like object. Hmmm, maybe someting
like this:
def __init__(self):
self.__dict__ = globals()
"something that I may want to refactor later"
s = GlobalSelf()
s.x += 1
43
 
A

Andrew Koenig

Alternatively, as someone else suggested, an analogue of the Pascal "with"
could be used:

def abs(self):
with self:
return math.sqrt(x**2 + y**2 + z**2)

How does your suggested "with" statement know to transform x into self.x but
not transform math.sqrt into self.math.sqrt?
 
C

Colin J. Williams

Andrew said:
How does your suggested "with" statement know to transform x into self.x but
not transform math.sqrt into self.math.sqrt?
I am not advocating this, but this could be:

def abs(self):
with self:
with math:
return sqrt(x**2 + y**2 + z**2)

The idea being that "with self" use
creates a new namespace:
newGlobal= oldGlobal + oldLocal
newLocal= names from self

Similarly, "with math" creates a newer
namespace:
newerGlobal= newGlobal + newLocal
newerLocal= names from math

My guess is that there would be little
use for nesting the
"with".

Colin W.
 
C

Colin J. Williams

Andrew said:
How does your suggested "with" statement know to transform x into self.x but
not transform math.sqrt into self.math.sqrt?
I am not advocating this, but this could be:

def abs(self):
with self:
with math:
return sqrt(x**2 + y**2 + z**2)

The idea being that "with self" use
creates a new namespace:
newGlobal= oldGlobal + oldLocal
newLocal= names from self

Similarly, "with math" creates a newer
namespace:
newerGlobal= newGlobal + newLocal
newerLocal= names from math

My guess is that there would be little
use for nesting the
"with".

Colin W.
 
A

Andrew Koenig

I am not advocating this, but this could be:
def abs(self):
with self:
with math:
return sqrt(x**2 + y**2 + z**2)
The idea being that "with self" use
creates a new namespace:
newGlobal= oldGlobal + oldLocal
newLocal= names from self

You don't know what those names are until runtime. Suppose, for example,
that self happens to have acquired an attribute named "math"? Then

with self:
with math:
return sqrt(x**2 + y**2 + z**2)

doesn't do what you expected, because "with math" turns out to have meant
"with self.math"
 
M

MonkeeSage

The issue of lexical scope still looms large on the horizon. How does
one distinguish between attributes (as scoped by the "with" clause),
local/global variables, and function/method calls? There doesn't seem
to be an easy way. You'd need multiple passes over the data to
determine various scopes -- and for what, to save typing a few
characters? And even if implemented, it would mean hiding the
complexity of the resolution, which is not a good thing.

Regards,
Jordan
 
C

Colin J. Williams

MonkeeSage said:
The issue of lexical scope still looms large on the horizon. How does
one distinguish between attributes (as scoped by the "with" clause),
local/global variables, and function/method calls? There doesn't seem
to be an easy way. You'd need multiple passes over the data to
determine various scopes -- and for what, to save typing a few
characters? And even if implemented, it would mean hiding the
complexity of the resolution, which is not a good thing.

Regards,
Jordan

Does this address your concerns?

The idea being that "with self" use
creates a new namespace:
newGlobal= oldGlobal + oldLocal
newLocal= names from self

Similarly, "with math" creates a newer
namespace:
newerGlobal= newGlobal + newLocal
newerLocal= names from math

My guess is that there would be little
use for nesting the
"with".


Colin W.
 
C

Colin J. Williams

MonkeeSage said:
The issue of lexical scope still looms large on the horizon. How does
one distinguish between attributes (as scoped by the "with" clause),
local/global variables, and function/method calls? There doesn't seem
to be an easy way. You'd need multiple passes over the data to
determine various scopes -- and for what, to save typing a few
characters? And even if implemented, it would mean hiding the
complexity of the resolution, which is not a good thing.

Regards,
Jordan

Does this address your concerns?

The idea being that "with self" use
creates a new namespace:
newGlobal= oldGlobal + oldLocal
newLocal= names from self

Similarly, "with math" creates a newer
namespace:
newerGlobal= newGlobal + newLocal
newerLocal= names from math

My guess is that there would be little
use for nesting the
"with".


Colin W.
 
A

Arnaud Delobelle

Below is my coding standard - I'm lazy, even lazy to persuade
comutinties into strange (imho) language syntax extensions.

class Vector:
def __init__(s, x, y, z):
s.x = x
s.y = y
s.z = z
def abs(s):
return math.sqrt(s.x * s.x + s.y * s.y + s.z * s.z)

Admit that changing habits may be more difficult then to change a
language syntax.

Jakub

occasional lamerish Python user

Well you're not the laziest. Here's mine:

class Vector:
def __init__(self, *data):
self.data = data
def abs(self):
return math.sqrt(sum(x*x for x in self.data))

Hey I'm so lazy it's untested :)
However I've got standards: I wouldn't swap 'self' for 's'.
 
B

BJörn Lindqvist

Below is my coding standard - I'm lazy, even lazy to persuade
comutinties into strange (imho) language syntax extensions.


class Vector:
def __init__(s, x, y, z):
s.x = x
s.y = y
s.z = z
def abs(s):
return math.sqrt(s.x * s.x + s.y * s.y + s.z * s.z)

Admit that changing habits may be more difficult then to change a
language syntax.

Yes, indeed. A self-reference prefix like "s", "T", "_" or even "my"
would be enough characters shorter than "self." But self *is* the
convention and just because the language allows you to break it
doesn't mean that it is not horribly wrong to do so. :)
 
B

Bruno Desthuilliers

Ton van Vliet a écrit :
On 24 Nov 2007 13:56:37 GMT, Marc 'BlackJack' Rintsch <[email protected]>
wrote: (snip)


Absolutely.

However, I was more thinking in terms of attributes only

Too bad : in Python, everything's an object, so 'methods' are attributes
too.
 
B

Bruno Desthuilliers

samwyse a écrit :
(snip)
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. ;-)

FWIW, Javascript has it too - and it's considered a BadPractice(tm) to
use it...
 
B

Bruno Desthuilliers

Ton van Vliet a écrit :
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.
In which case explicitely making local aliases is not too much work, and
way more readable.
 
B

Bruno Desthuilliers

Patrick Mullen a écrit :
(snip)
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

self.__dict__.update(dict(var1=5, var2="a value", var3 = stuff, <etc>))

Someone else ? Or are we done with this DeadHorse ?
 
B

Bruno Desthuilliers

samwyse a écrit :
(snip)
Actually, the chained dots are solving a completely different problem,
that of refactoring a collection of functions that use global vars
into a class.

Using globals to maintain state between functions being bad practice in
most cases, I don't see any reason to encourage it by providing some
builtin support.
 
T

Ton van Vliet

Too bad : in Python, everything's an object, so 'methods' are attributes
too.

Right, but I'm sure *you* know a way to distinguish between them (I'm
just a beginner ;-)
 
C

Colin J. Williams

Bruno Desthuilliers wrote:
[snip]>
Too bad : in Python, everything's an object, so 'methods' are attributes
too.

What do you see as a problem here?
Surely it gives useful flexibility.

Colin W.
 
S

Steven D'Aprano

Right, but I'm sure *you* know a way to distinguish between them (I'm
just a beginner ;-)

All methods are attributes. Not all attributes are methods. The usual way
to see if something is a method is to try calling it and see what
happens, but if you want a less informal test, try type():

<type 'instancemethod'>
 
B

Bruno Desthuilliers

Steven D'Aprano a écrit :
Yes : reading the doc. But that's something the compiler will have hard
time doing.
All methods are attributes. Not all attributes are methods. The usual way
to see if something is a method is to try calling it and see what
happens, but if you want a less informal test, try type():


<type 'instancemethod'>


Fine. Now since Python let you define your own callable types and your
own descriptors, you can as well have an attribute that behave just like
a method without being an instance of any of the method types - so the
above test defeats duck typing. And since you can have callable
attributes that are definitively not methods, you can't rely on the fact
that an attribute is callable neither.
 
R

Roy Smith

Steven D'Aprano a écrit :

Yes : reading the doc. But that's something the compiler will have hard
time doing.



Fine. Now since Python let you define your own callable types and your
own descriptors, you can as well have an attribute that behave just like
a method without being an instance of any of the method types - so the
above test defeats duck typing. And since you can have callable
attributes that are definitively not methods, you can't rely on the fact
that an attribute is callable neither.

If you want to have a little fun:

class peverse:
def __call__(self):
raise AttributeError ("peverse instance has no __call__ method")

x = peverse()
x()
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,161
Latest member
GertrudeMa
Top