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

Deprecate self

1 view
Skip to first unread message

Vadim Chugunov

unread,
Apr 18, 2001, 4:47:29 AM4/18/01
to

"Dave LeBlanc" <whi...@oz.net> wrote in message
news:9bji5k$417$0...@216.39.170.247...
> Since self is used for every method of every class, isn't it a bit
> redundant? I don't know of another OO language that makes you manually
> carry around the "this"/"self" pointer/reference...

Sure, we could get rid of 'self'. ...and then immediately invent coding
convention that allows people to distinguish class variables from globals
and locals. Like 'm_spam'.

When 'self' seems to be too much typing I shorten it to 's'.

Alex Martelli

unread,
Apr 18, 2001, 4:59:09 AM4/18/01
to
"Dave LeBlanc" <whi...@oz.net> wrote in message
news:9bji5k$417$0...@216.39.170.247...
> Since self is used for every method of every class, isn't it a bit
> redundant?

Not really. Explicit is better than implicit.

> I don't know of another OO language that makes you manually
> carry around the "this"/"self" pointer/reference...

Modula-3, for example (I believe 'self' is a reserved word
there; in Python, it's "just" a 'universal' convention).

> Of course being new around here, i'm unaware if this has been hissed
> over in depth previously :-)

Of course. I believe it was first debated sometime
in 1994, and, of course, since people don't search
archives before posting, uncounted times since:-)

http://www.cwi.nl/www.python.org/search/hypermail/python-1994q2/0511.html


Alex

Martin von Loewis

unread,
Apr 18, 2001, 7:51:54 AM4/18/01
to
whi...@oz.net (Dave LeBlanc) writes:

> Since self is used for every method of every class, isn't it a bit

> redundant? I don't know of another OO language that makes you manually


> carry around the "this"/"self" pointer/reference...

In Smalltalk, invocations of operations on self always require to
provide the self argument. You don't have to declare it as a method
argument, though.

Regards,
Martin

Grant Edwards

unread,
Apr 18, 2001, 9:54:55 AM4/18/01
to
In article <lc8zkye...@gaffa.mit.edu>, Douglas Alan wrote:

>> Since self is used for every method of every class, isn't it a bit
>> redundant?
>

>Many people find it less confusing to read code that is written this
>way. Otherwise, when you see a variable, you have more choices as to
>where the variable might be defined: the local scope, the global
>scope, the class scope, etc.


>
>> I don't know of another OO language that makes you manually carry
>> around the "this"/"self" pointer/reference...
>

>Languages with multimethods routinely do, because multimethods are
>typically not class-centric. I.e., a generic function in a language
>with multimethods dispatches on all the arguments, not just on one of
>them, so no particular argument is given special treatment.
>
>For class-centric OO languages, I agree with you -- I don't personally
>know of any others that require explicit use of self.

Smalltalk and Modula-3 both do, IIRC.

--
Grant Edwards grante Yow! We just joined the
at civil hair patrol!
visi.com

Rainer Deyke

unread,
Apr 18, 2001, 10:29:57 AM4/18/01
to
"Dave LeBlanc" <whi...@oz.net> wrote in message
news:9bji5k$417$0...@216.39.170.247...
> Since self is used for every method of every class, isn't it a bit
> redundant? I don't know of another OO language that makes you manually

> carry around the "this"/"self" pointer/reference...

My C++ code has become much more readable since I started referring to
member variables through 'this'.


--
Rainer Deyke (ro...@rainerdeyke.com)
Shareware computer games - http://rainerdeyke.com
"In ihren Reihen zu stehen heisst unter Feinden zu kaempfen" - Abigor


Rainer Deyke

unread,
Apr 18, 2001, 10:40:41 AM4/18/01
to
"Alex Martelli" <ale...@yahoo.com> wrote in message
news:9bjl2...@news1.newsguy.com...

> "Dave LeBlanc" <whi...@oz.net> wrote in message
> news:9bji5k$417$0...@216.39.170.247...
> > Since self is used for every method of every class, isn't it a bit
> > redundant?
>
> Not really. Explicit is better than implicit.

The thing that bothers me about using 'self' is that it is inconsistent.
The relationship of a method to the object on which it is called is
analogous to the relationship between a free function and its module, yet
only the former supports the 'self.x' convention. I could do this:

# Module spam.py
import spam
x = 5

def f():
print spam.x

However, this is still inconsistent because the name 'spam' is already
accessed through the global namespace. I could do this:

# Module eggs.py
import eggs
x = 5

def f(self_module=eggs):
print self_module.x

However, this does not work if 'f' takes a variable number of argument (and
is tedious besides). In C++, I can explicitly qualify global variables:

namespace jam {
int x = 5;
void f()
{
std::cout << ::jam::x << std::endl;
}
}

Another thing that C++ got right and Python got wrong.

pi...@cs.uu.nl

unread,
Apr 18, 2001, 10:36:10 AM4/18/01
to
>>>>> "Alex Martelli" <ale...@yahoo.com> (AM) writes:

AM> "Dave LeBlanc" <whi...@oz.net> wrote in message
AM> news:9bji5k$417$0...@216.39.170.247...


>> Since self is used for every method of every class, isn't it a bit
>> redundant?

AM> Not really. Explicit is better than implicit.

>> I don't know of another OO language that makes you manually
>> carry around the "this"/"self" pointer/reference...

AM> Modula-3, for example (I believe 'self' is a reserved word
AM> there; in Python, it's "just" a 'universal' convention).

And Corbascript/IDLscript, which heavily borrowed concepts from Python
--
Piet van Oostrum <pi...@cs.uu.nl>
URL: http://www.cs.uu.nl/~piet [PGP]
Private email: P.van....@hccnet.nl

Jeremy Hylton

unread,
Apr 18, 2001, 10:49:12 AM4/18/01
to Dave LeBlanc, pytho...@python.org
>>>>> "MvL" == Martin von Loewis <loe...@informatik.hu-berlin.de> writes:

MvL> whi...@oz.net (Dave LeBlanc) writes:
>> Since self is used for every method of every class, isn't it a
>> bit redundant? I don't know of another OO language that makes you
>> manually carry around the "this"/"self" pointer/reference...

MvL> In Smalltalk, invocations of operations on self always require
MvL> to provide the self argument. You don't have to declare it as a
MvL> method argument, though.

Modula-3 was mentioned in another post.

There is a reason other than simple clarity (I like using an explicit
self) for this approach. Python's rules for local variables would
interfere with attribute access. Since Python eschews variable
declarations, any assignment to a name inside a code block makes that
name a local variable. By this rule alone, there would never by a way
to assign to an instance variable :-). You'd need a mechanism like
the global statement to say "This name isn't a local."

We had an opportunity to change the attribute access approach when
nested scopes were introduced, but we went out of our way (well, sort
of) to preserve the self.attr approach.

Jeremy

Fredrik Lundh

unread,
Apr 18, 2001, 11:18:58 AM4/18/01
to
Vadim Chugunov wrote:
> Sure, we could get rid of 'self'. ...and then immediately invent coding
> convention that allows people to distinguish class variables from globals
> and locals. Like 'm_spam'.

before you get that far, you have to invent something that
allows *python* to distinguish class variables from globals
and locals...

Cheers /F


Fredrik Lundh

unread,
Apr 18, 2001, 11:18:57 AM4/18/01
to
Dave LeBlanc wrote:
> Since self is used for every method of every class, isn't it a bit
> redundant? I don't know of another OO language that makes you manually
> carry around the "this"/"self" pointer/reference...
>
> Of course being new around here, i'm unaware if this has been hissed
> over in depth previously :-)

http://www.python.org/doc/FAQ.html#6.7

Q. Why must 'self' be declared and used explicitly in
method definitions and calls?

A. So, is your current programming language C++ or
Java? :-) /.../ The idea was borrowed from Modula-3.
It turns out to be very useful, for a variety of reasons
/.../

Cheers /F


Erik Max Francis

unread,
Apr 18, 2001, 11:19:25 AM4/18/01
to
Dave LeBlanc wrote:

> Since self is used for every method of every class, isn't it a bit
> redundant? I don't know of another OO language that makes you manually
> carry around the "this"/"self" pointer/reference...

It is better to have it be explicit, and changing it would break lots of
code, anyway.

--
Erik Max Francis / m...@alcyone.com / http://www.alcyone.com/max/
__ San Jose, CA, US / 37 20 N 121 53 W / ICQ16063900 / &tSftDotIotE
/ \ War is the province of chance.
\__/ Karl von Clausewitz
7 sisters productions / http://www.7sisters.com/
Web design for the future.

Steve Purcell

unread,
Apr 18, 2001, 11:10:43 AM4/18/01
to Rainer Deyke, pytho...@python.org
Rainer Deyke wrote:
> My C++ code has become much more readable since I started referring to
> member variables through 'this'.

I had the same experience with Java. Writing 'this' also helps to avoid
having to artificially mutate variable names that are logically related
in code such as:

class Blah {
Foo foo;
Blah(Foo foo) {
this.foo = foo;
}
...
}

Now, I've admittedly been corrupted by Python, but I know some Java purists
who like this ('this'?) style too.

-Steve

--
Steve Purcell, Pythangelist
Get testing at http://pyunit.sourceforge.net/
Any opinions expressed herein are my own and not necessarily those of Yahoo

Luke

unread,
Apr 18, 2001, 12:17:02 PM4/18/01
to
Java's system works just fine. It is assumed when you are writing a class,
that a variable is part of that class. It makes more sense. After all why
wouldn't you assume first that a variable that is part of a class belongs to
that class. If you are dumb and want to put an identical variable in a local
scope in a function, for example, then you use this.foo to distinguish. Java
is more logical IMHO

Alex Martelli

unread,
Apr 18, 2001, 11:29:43 AM4/18/01
to
"Rainer Deyke" <ro...@rainerdeyke.com> wrote in message
news:JHhD6.43991$J%5.148...@news2.rdc2.tx.home.com...

> "Alex Martelli" <ale...@yahoo.com> wrote in message
> news:9bjl2...@news1.newsguy.com...
> > "Dave LeBlanc" <whi...@oz.net> wrote in message
> > news:9bji5k$417$0...@216.39.170.247...
> > > Since self is used for every method of every class, isn't it a bit
> > > redundant?
> >
> > Not really. Explicit is better than implicit.
>
> The thing that bothers me about using 'self' is that it is inconsistent.

Not really.

> The relationship of a method to the object on which it is called is
> analogous to the relationship between a free function and its module, yet

Aha, here's where you see the inconsistency. The analogy is just
not there. A method may be called on objects that are not in its
class (but rather in a descendant one) while there is nothing of
the kind about a function -- it's not called "on" a module, much
less "on" a module somehow different from the one where it gets
defined. It's not surprising that you find inconsistency where
the analogy you thought you saw was never really there.

The module is, basically, just a namespace. A function, _and_ btw
a method too, can access that namespace implicitly or explicitly
[eg via globals()]. It would make no sense for it to be an argument
to the function since it doesn't change at each call -- while the
instance on which a method is being called CAN definitely differ
at each call.

> However, this does not work if 'f' takes a variable number of argument
(and
> is tedious besides). In C++, I can explicitly qualify global variables:

So you can in Python, if you wish -- globals() lets you do that
most easily.


> namespace jam {
> int x = 5;
> void f()
> {
> std::cout << ::jam::x << std::endl;
> }
> }
>
> Another thing that C++ got right and Python got wrong.

The intricacies of C++ scoping can hardly be taken as an example
of things "C++ got right". Can you spell "Koenig lookup" and
name two major current C++ implementations that get it wrong?

Python's scoping is crystal-simple (up to 2.1 excluded -- I have
not yet delved into the new lexical scoping things deep enough
to underwrite their simplicity, although one does hope from PEP
reading & such things:-). C++'s is one of the most complex
areas in an overly-complex language ('overly' when compared
with human mental capacity, mind you -- I'm not claiming it
could meet its aggressive design goals with simplicity, just
that maybe those design goals were too aggressive). Please
note that I'm a Brainbench MVP for the C++ language, which,
among other things, means I must be in the upper centile of
scorers in their quiz-like tests -- I'd better, since one of
the main activities that keeps good soup on my table is C++
guruhood/consultancy for my employer (COM is much of the rest,
but, for all of its pragmatical complications, the COM specs
themselves are really much simpler than the ISO C++ Standard;
in COM's case, the complications come on top, in the huge
variety of interfaces and technologies layered on it, geared
to its implementation and support, etc, etc).

In other words, my dislike for C++'s complexities is NOT due
to insufficient familiarity with them -- indeed, maybe the
reverse, since I spend so much of my time and energy in
clarifying the finer points of several combinations of very
obscure provisions & implementations' bugs to highly skilled
software development professionals that keep getting badly
burned by all of the tripwires (I insist that you HAVE to
mix metaphors A LOT to get into the spirit of C++...:-).

Don't get me wrong -- for all that, C++'s still what I use
by choice to extend or embed Python or implement custom COM
stuff &c. But, to quote Joy out of context, "Sometimes
when you fill a vacuum it still sucks" (others say it was
Pike, Ritchie, or other such luminaries, who said it first).


Alex

Alex Martelli

unread,
Apr 18, 2001, 11:36:12 AM4/18/01
to
"Rainer Deyke" <ro...@rainerdeyke.com> wrote in message
news:FxhD6.43909$J%5.148...@news2.rdc2.tx.home.com...

> "Dave LeBlanc" <whi...@oz.net> wrote in message
> news:9bji5k$417$0...@216.39.170.247...
> > Since self is used for every method of every class, isn't it a bit
> > redundant? I don't know of another OO language that makes you manually
> > carry around the "this"/"self" pointer/reference...
>
> My C++ code has become much more readable since I started referring to
> member variables through 'this'.

I agree on this point, but trying to make 200 dyed-in-the-wool
C++ programmers start using this->foo everywhere is turning out
to be pretty hard despite "acknowledged C++ guruhood":-).


Alex

Fredrik Lundh

unread,
Apr 18, 2001, 12:23:06 PM4/18/01
to
"Luke" trolls again:

looks like you haven't studied Python's class model close enough
to actually know what you're talking about here...

(hint: how do you declare class members in Python?)

Cheers /F


Dave LeBlanc

unread,
Apr 18, 2001, 12:35:45 PM4/18/01
to
Said reasons being?

Sending me money turns out to be very useful for a variety of
reasons... convinced?

Dave LeBlanc

Dave LeBlanc

unread,
Apr 18, 2001, 12:40:48 PM4/18/01
to
Smalltalk never requres the declaration of self as an arguement to a
method. self is only used to identify the target (variable or method
invocation) as being local to the caller (i.e. in it's own class
scope). It's been awhile, so I don't recall if it's mandatory in that
context or not.

I was going to mention super, but given the multiple inheritance
nature of Python, it wouldn't work.

Dave LeBlanc

On Wed, 18 Apr 2001 13:54:55 GMT, gra...@visi.com (Grant Edwards)
wrote:

Harry George

unread,
Apr 18, 2001, 12:09:29 PM4/18/01
to
In Modula-3, I think "self" is not reserved -- you can use other names
for the first arg. Further, you can call the method as a standalone
function or procedure as long as you supply the arg directly. I do
(did) this regularly in Modula-3 in conjunction with partial
revelation. It even seems to work in python:


#method signature:
def from_tadef(self,fileobj,style="tadef")

#usage:
t=Tadef_File()
#---method calls---
t.from_tadef(filename)
t.to_tadef(filename+".out")
#---function calls---
Tadef_File.from_tadef(t,filename)
Tadef_File.to_tadef(t,filename+".out")

Obviously, in the standalone mode, you cannot rely on an implied
"self" -- it is just another argument.

pi...@cs.uu.nl writes:

--
Harry George E-mail: harry.g...@boeing.com
The Boeing Company Renton: (425) 237-6915
P. O. Box 3707 02-CA Everett: (425) 266-3868
Seattle, WA 98124-2207 Page: (425) 631-8803

Fredrik Lundh

unread,
Apr 18, 2001, 12:54:40 PM4/18/01
to
Dave LeBlanc wrote:
> Said reasons being?

follow the link, and find out for yourself...

Cheers /F


Steve Purcell

unread,
Apr 18, 2001, 12:26:02 PM4/18/01
to pytho...@python.org
D-Man wrote:
> It doesn't work quite as nicely with inner classes though :

Probably the following will work:

Bar.this.doSomething() ;

instead of
this.doSomething() ;

Anyway, Jikes isn't the most reliable java compiler when it comes to
inner classes. Your example will probably work fine with javac.

D-Man

unread,
Apr 18, 2001, 12:00:47 PM4/18/01
to pytho...@python.org, Steve Purcell, Rainer Deyke
On Wed, Apr 18, 2001 at 05:10:43PM +0200, Steve Purcell wrote:
| Rainer Deyke wrote:
| > My C++ code has become much more readable since I started referring to
| > member variables through 'this'.
|
| I had the same experience with Java. Writing 'this' also helps to avoid
| having to artificially mutate variable names that are logically related
| in code such as:
...
| Now, I've admittedly been corrupted by Python,

Same here.

It doesn't work quite as nicely with inner classes though :

public class Bar extends JFrame
{
public Bar()
{
JButton b = new JButton( "Hello" ) ;
b.addActionListener( new ActionListener()
{
public void actionPerformed( ActionEvent e )
{
this.doSomething() ;
}
} ) ;

this.getContentPane().add( b ) ;
}

public void doSomething()
{
System.out.println( "Button pressed" ) ;
}
}



$ jikes -classpath d:/jdk1.2.2/lib/rt.jar Bar.java

Found 1 semantic error compiling "D:/apps/cygwin/home/derrick/tmp/random_checks/
Bar.java":

15. this.doSomething() ;
<---------------->
*** Error: No method named "doSomething" was found in type "Bar$1".


OTOH inner classes are used so heavily because functions aren't
objects and thus can't be used as callbacks/event handlers


-D


David C. Browne

unread,
Apr 18, 2001, 1:08:01 PM4/18/01
to
How about checking the URL he furnished you?


Dave LeBlanc wrote:

--
David Browne
David....@sdrc.com
Eugene, OR

"The ignorant are ignorant of their ignorance."

Grant Griffin

unread,
Apr 18, 2001, 12:20:10 PM4/18/01
to
In article <9bji5k$417$0...@216.39.170.247>, whi...@oz.net says...

>
>Since self is used for every method of every class, isn't it a bit
>redundant?

No more than the phrase "a _bit_ redundant" <wink>.

Actually, there are both practical and aesthetic reasons for "self". I won't
bore you with them except to say that the aesthetic reasons are based in the
Tim's axiom "explict is better than implicit".

>I don't know of another OO language that makes you manually
>carry around the "this"/"self" pointer/reference...

Then you obviously haven't read the other responses to your post. <wink>

>
>Of course being new around here, i'm unaware if this has been hissed
>over in depth previously :-)

Sure. Moral of the story: Python and its users have high self-esteem.

it'll-grow-on-you-ly y'rs,

=g2

_____________________________________________________________________

Grant R. Griffin g...@dspguru.com
Publisher of dspGuru http://www.dspguru.com
Iowegian International Corporation http://www.iowegian.com

Samuel A. Falvo II

unread,
Apr 18, 2001, 1:37:14 PM4/18/01
to
On 18 Apr 2001 08:10:28 GMT, Dave LeBlanc wrote:
>Since self is used for every method of every class, isn't it a bit
>redundant? I don't know of another OO language that makes you manually

>carry around the "this"/"self" pointer/reference...

Oberon.

--
KC5TJA/6, DM13, QRP-L #1447
Samuel A. Falvo II
Oceanside, CA

Luke

unread,
Apr 18, 2001, 1:42:25 PM4/18/01
to
> looks like you haven't studied Python's class model close enough
> to actually know what you're talking about here...
>
> (hint: how do you declare class members in Python?)
>
> Cheers /F

That's my point exactly. You don't need it.

Samuel A. Falvo II

unread,
Apr 18, 2001, 1:43:25 PM4/18/01
to
On Wed, 18 Apr 2001 14:40:41 GMT, Rainer Deyke wrote:
>namespace jam {
> int x = 5;
> void f()
> {
> std::cout << ::jam::x << std::endl;
> }
>}
>
>Another thing that C++ got right and Python got wrong.

I::think Python::has::better scoping::designator ::though. ::-)

Marcin 'Qrczak' Kowalczyk

unread,
Apr 18, 2001, 1:53:56 PM4/18/01
to
Wed, 18 Apr 2001 14:40:41 GMT, Rainer Deyke <ro...@rainerdeyke.com> pisze:

> The thing that bothers me about using 'self' is that it is inconsistent.

So let's allow
def self.method(arg1, arg2):
to have the definition syntax consistent with a call.

> The relationship of a method to the object on which it is called
> is analogous to the relationship between a free function and its
> module, yet only the former supports the 'self.x' convention.

Indeed there is a correspondence.

The difference is that the function will get an object as an additional
argument if it's obtained from a class, but it won't get anything if
it's obtained from a module (the "anything" would have to be related
to the module as instance is related to its class, and there is even
no such thing).

The syntactic difference is a result of a semantic difference.

--
__("< Marcin Kowalczyk * qrc...@knm.org.pl http://qrczak.ids.net.pl/
\__/
^^ SYGNATURA ZASTĘPCZA
QRCZAK

Siggy Brentrup

unread,
Apr 18, 2001, 1:01:44 PM4/18/01
to pytho...@python.org
whi...@oz.net (Dave LeBlanc) writes:

> Said reasons being?
>
> Sending me money turns out to be very useful for a variety of
> reasons... convinced?

In contrast to /F, you didn't give a URL to look up your ..., so why
would anyone pay you for being too lazy to read the FAQ ?

> On Wed, 18 Apr 2001 15:18:57 GMT, "Fredrik Lundh"
> <fre...@pythonware.com> wrote:
>
> >Dave LeBlanc wrote:

[...]

> >http://www.python.org/doc/FAQ.html#6.7

[...]

Cheers
Siggy

--
Siggy Brentrup - b...@winnegan.de - http://www.winnegan.de/
****** ceterum censeo javascriptum esse restrictam *******


Rainer Deyke

unread,
Apr 18, 2001, 3:18:06 PM4/18/01
to
"Alex Martelli" <ale...@yahoo.com> wrote in message
news:9bkc0...@news1.newsguy.com...

> "Rainer Deyke" <ro...@rainerdeyke.com> wrote in message
> news:JHhD6.43991$J%5.148...@news2.rdc2.tx.home.com...
> > The relationship of a method to the object on which it is called is
> > analogous to the relationship between a free function and its module,
yet
>
> Aha, here's where you see the inconsistency. The analogy is just
> not there. A method may be called on objects that are not in its
> class (but rather in a descendant one) while there is nothing of
> the kind about a function -- it's not called "on" a module, much
> less "on" a module somehow different from the one where it gets
> defined. It's not surprising that you find inconsistency where
> the analogy you thought you saw was never really there.

The analogy is not universally applicable, but it is most certainly "there".
Consider singletons (i.e. classes which by design only have a single
instance and no subclasses). Or consider random number generators. The
documentation specifies an interface for random number generators which I
can implement through a module (like module 'random'). If I later decide I
need more than one instance of my random number generator with seperate
state, I can move the functions of that module into a class and use intances
of that class to generate random numbers. This requires that I add 'self'
as first argument to all functions and 'self.' before all state accesses: a
tedious and error-prone process.

> The module is, basically, just a namespace.

So is a class. So is a class instance.

class colors:
red = 0
green = 1
blue = 3

class EmptyClass: pass
state = EmptyClass()
state.frame = 0


> A function, _and_ btw
> a method too, can access that namespace implicitly or explicitly
> [eg via globals()]. It would make no sense for it to be an argument
> to the function since it doesn't change at each call -- while the
> instance on which a method is being called CAN definitely differ
> at each call.
>
> > However, this does not work if 'f' takes a variable number of argument
> (and
> > is tedious besides). In C++, I can explicitly qualify global variables:
>
> So you can in Python, if you wish -- globals() lets you do that
> most easily.

'globals()' is syntactically awkward and semantically different from
attribute access.

# Module spam.py
import spam

print spam.__dict__
print globals()['__dict__']

A module importing itself is still the best idiom here.


> > namespace jam {
> > int x = 5;
> > void f()
> > {
> > std::cout << ::jam::x << std::endl;
> > }
> > }
> >
> > Another thing that C++ got right and Python got wrong.
>
> The intricacies of C++ scoping can hardly be taken as an example
> of things "C++ got right".

I'm not talking about the intricacies of C++ scoping, but this very specific
case.

> Python's scoping is crystal-simple (up to 2.1 excluded -- I have
> not yet delved into the new lexical scoping things deep enough
> to underwrite their simplicity, although one does hope from PEP
> reading & such things:-).

Lack of lexical scoping is another thing Python got wrong. It causes code
not to work when moved from one scope to another. However, I had not
intended to start a general discussion of scoping in programming languages.

> In other words, my dislike for C++'s complexities is NOT due
> to insufficient familiarity with them -- indeed, maybe the
> reverse, since I spend so much of my time and energy in
> clarifying the finer points of several combinations of very
> obscure provisions & implementations' bugs to highly skilled
> software development professionals that keep getting badly
> burned by all of the tripwires (I insist that you HAVE to
> mix metaphors A LOT to get into the spirit of C++...:-).

I understand very much the value of simplicity and the horror of C++'s
complexity. I see inconsitency and over-specialized syntax as the primary
causes, so I attack them in language design whereever I find it - even in
mostly sane languages like Python.

Just van Rossum

unread,
Apr 18, 2001, 4:31:28 PM4/18/01
to
[Rainer Deyke]

> The relationship of a method to the object on which it is called is
> analogous to the relationship between a free function and its module,

[Alex Martelli]


> Aha, here's where you see the inconsistency. The analogy is just

> not there. [ ... ]

[Rainer]


> The analogy is not universally applicable, but it is most certainly "there".

Modules don't have instances. Sure, modules are in many ways like classes,
but they're not at all like instances. And only with instances the self
discussion becomes interesting. Your analogy is moot.

[Alex]


> Python's scoping is crystal-simple (up to 2.1 excluded -- I have
> not yet delved into the new lexical scoping things deep enough
> to underwrite their simplicity, although one does hope from PEP
> reading & such things:-).

[Rainer]


> Lack of lexical scoping is another thing Python got wrong.

Eh? Python _has_ lexical scoping (but scopes can't nest until 2.1).

> It causes code
> not to work when moved from one scope to another. However, I had not
> intended to start a general discussion of scoping in programming languages.

Have you looked at the (optional, for now) new scoping rules in 2.1 that
Alex alluded to?

Just

Samuel A. Falvo II

unread,
Apr 18, 2001, 4:51:58 PM4/18/01
to
On Wed, 18 Apr 2001 22:31:28 +0200, Just van Rossum wrote:
>Modules don't have instances. Sure, modules are in many ways like classes,
>but they're not at all like instances. And only with instances the self
>discussion becomes interesting. Your analogy is moot.

Modules are every bit like instances -- a singleton instance, to be
specific. They expose an interface, and maintain state -- just like any
object. Internally, they're even represented by the same data structure as
an object.

What they don't do is inherit functionality from other modules, but even
that can be emulated with stuff like:

import foo

FooFunc1 = foo.FooFunc1
FooFunc2 = foo.FooFunc2
# ... etc...

Because they expose an interface, a module can be treated as an instance of
a class defined by the global definitions of that module (it's a recursive
definition, and this is why other dynamic OO environments have the concept
of "meta-classes" as well as classes, so as to break this recursion).

Alex Martelli

unread,
Apr 18, 2001, 5:03:53 PM4/18/01
to
"Rainer Deyke" <ro...@rainerdeyke.com> wrote in message
news:OLlD6.46125$J%5.153...@news2.rdc2.tx.home.com...
[snip]

> > Aha, here's where you see the inconsistency. The analogy is just
> > not there. A method may be called on objects that are not in its
[snip]

> The analogy is not universally applicable, but it is most certainly
"there".

About at the same level as that between ravens and writing desks
(I'm sure you are familiar with Carroll's works, right?). At a sufficiently
weak level, you can analogize everything and anything. That doesn't
mean it makes any _sense_ to do so, of course.

> Consider singletons (i.e. classes which by design only have a single
> instance and no subclasses).

How do you stop a class from having subclasses in Python? (And
what is the supposed benefit of that -- assuming you can find any
benefits for the singleton DP anywhere, of course).

> Or consider random number generators. The
> documentation specifies an interface for random number generators which I
> can implement through a module (like module 'random'). If I later decide
I
> need more than one instance of my random number generator with seperate
> state, I can move the functions of that module into a class and use
intances
> of that class to generate random numbers. This requires that I add 'self'
> as first argument to all functions and 'self.' before all state accesses:
a
> tedious and error-prone process.

Finally, a point. Yes, a very deep refactoring such as changing a module
into a class, since they're very different things, will require many
changes.

Among them, besides the ones you note, will probably be the introduction
of inheritance to capture code commonality and a lot of decision to make
about what state is per-class and what is per-instance (not to mention
similar decisions about callables).

The task of helping with such refactoring chores, of course, is properly
one for editing-time tools; it would be pretty foolish to distort a language
to make it easier to do with a dumb editor part of what one should really
be using a refactoring-browser or similar tool to accomplish.


> > The module is, basically, just a namespace.
>
> So is a class. So is a class instance.

Except (for example) that classes have inheritance, while modules do
not, and instances have rich lookup instance->class->bases, while,
again, modules do not. So a class or instance is in fact NOT just a
namespace but a _structured_ one.

> class colors:
> red = 0
> green = 1
> blue = 3
>
> class EmptyClass: pass
> state = EmptyClass()
> state.frame = 0

And x=colors(); x.red=22, whereupon you get the instance dictionary
"overriding" (so to speak) the class one on any getattr. Not JUST a
namespace, see? Which is why 'self' is needed as an argument to
methods, and access that go through it are so different from ones
that don't.


> > A function, _and_ btw
> > a method too, can access that namespace implicitly or explicitly
> > [eg via globals()]. It would make no sense for it to be an argument
> > to the function since it doesn't change at each call -- while the

I note you have signally failed to address this horrid defect in the
analogy you claim "is there". A method has a global namespace
_as well_ as access to self as an argument. If functions were to
access their global namespace though some magic overloading of
self, how WOULD methods access THEIR global namespace?


> > instance on which a method is being called CAN definitely differ
> > at each call.
> >
> > > However, this does not work if 'f' takes a variable number of argument
> > (and
> > > is tedious besides). In C++, I can explicitly qualify global
variables:
> >
> > So you can in Python, if you wish -- globals() lets you do that
> > most easily.
>
> 'globals()' is syntactically awkward and semantically different from
> attribute access.

Yes, for special attributes. Just as in C++ namespace qualification is
syntactically and semantically different from attribute access, too, save
that the Python situation is simpler. As you chose to assert this is done
right in C++, you're being inconsistent in bemoaning "similar
differences" (interesting pseudo-oxymoron here:-) in Python.


> # Module spam.py
> import spam
> print spam.__dict__
> print globals()['__dict__']
>
> A module importing itself is still the best idiom here.

Your choice. I prefer globals(), myself.


> > > namespace jam {
> > > int x = 5;
> > > void f()
> > > {
> > > std::cout << ::jam::x << std::endl;
> > > }
> > > }
> > >
> > > Another thing that C++ got right and Python got wrong.
> >
> > The intricacies of C++ scoping can hardly be taken as an example
> > of things "C++ got right".
>
> I'm not talking about the intricacies of C++ scoping, but this very
specific
> case.

A case that will crash and burn as soon as this gets wrapped into
another namespace (as will no doubt have to happen soon, since
first thing you know code will have to use this AND another silly
library using a similarly uninspired namespace name)...? Please.

This use of namespaces is NOT good C++ style. Sure, you can
do it -- and get away with it as long as you're playing with toy
sized systems, maybe. In real large-scale C++ software, though,
you had better stick to canonic use. Please see Meyers' Effective
C++, CDROM edition, for the most elementary and fundamental
basics. Koenig and Moo in "Ruminations on C++" have quite
usable material, too. To make a long story short, namespaces
ARE meant for large-scale software and the top-level namespaces
had better be unique. You'll use using-declarations to make such
long unique namespaces usable.


> > Python's scoping is crystal-simple (up to 2.1 excluded -- I have
> > not yet delved into the new lexical scoping things deep enough
> > to underwrite their simplicity, although one does hope from PEP
> > reading & such things:-).
>
> Lack of lexical scoping is another thing Python got wrong. It causes code
> not to work when moved from one scope to another. However, I had not
> intended to start a general discussion of scoping in programming
languages.

Yet that's what you did -- because (while making no actual usable
proposals) you started bemoaning the use of self in methods and/or
its non-use in module-level functions. These ARE scoping issues,
after all. Could you really not be aware of that fact?


> > In other words, my dislike for C++'s complexities is NOT due
> > to insufficient familiarity with them -- indeed, maybe the
> > reverse, since I spend so much of my time and energy in
> > clarifying the finer points of several combinations of very
> > obscure provisions & implementations' bugs to highly skilled
> > software development professionals that keep getting badly
> > burned by all of the tripwires (I insist that you HAVE to
> > mix metaphors A LOT to get into the spirit of C++...:-).
>
> I understand very much the value of simplicity and the horror of C++'s
> complexity. I see inconsitency and over-specialized syntax as the primary
> causes, so I attack them in language design whereever I find it - even in
> mostly sane languages like Python.

What would the "over-specialized syntax" you are attacking be
in this case? Please be specific. I see nothing over-specialized
in a method or function receiving an object and accessing its
attributes with dot syntax, while both access global names
without such qualification:

x = 23

def afun(obj):
print x
print obj.x

class Aclass:
x = 45
def amet(self):
print x
print self.x

The "print x" refers to the global module x in each case, while
the Z.x for some Z (which happens to be the first argument in
each case) refers to attribute x of object Z. Total consistency
(indeed, identity) and no specialized syntax whatsoever. So,
are you seeing ghosts?


Alex

D-Man

unread,
Apr 18, 2001, 5:09:28 PM4/18/01
to pytho...@python.org

[Luke wrote:]

| Java's system works just fine. It is assumed when you are writing a
| class, that a variable is part of that class. It makes more sense.
| After all why

Are you sure? Did you write 'static' or not? If not, it is part of
an _instance_ of the class, not the class itself.

You declare _class_ members by assigning to them in the _class_ body.
You can't declare (or change the value of) _class_ members inside the
body of a function in the class unless you explicitly use the class
name.

Now I think you really mean _instance_ members. How do you declare
instance members in Python?

-D


D-Man

unread,
Apr 18, 2001, 5:21:54 PM4/18/01
to pytho...@python.org, Steve Purcell
On Wed, Apr 18, 2001 at 06:26:02PM +0200, Steve Purcell wrote:
| D-Man wrote:
| > It doesn't work quite as nicely with inner classes though :
|
| Probably the following will work:
|
| Bar.this.doSomething() ;
|
| instead of
| this.doSomething() ;

Yes, but it still isn't the prettiest thing.

| Anyway, Jikes isn't the most reliable java compiler when it comes to
| inner classes. Your example will probably work fine with javac.

Nope, javac says the same thing (just spelled slightly differently
;-)). After all, with the inner class you have a new object. That
object can be referred to by 'this' inside (non-static) methods of the
class. Thus I want 'this' to magically unambiguously refer to two
different objects at the same time.

-D

BTW, Where have you seen a problem with jikes? (this should probably
be taken off-list since it is java specific, not actually python
related)

Rainer Deyke

unread,
Apr 18, 2001, 7:56:11 PM4/18/01
to
"Alex Martelli" <ale...@yahoo.com> wrote in message
news:9bkvi...@news1.newsguy.com...

> "Rainer Deyke" <ro...@rainerdeyke.com> wrote in message
> news:OLlD6.46125$J%5.153...@news2.rdc2.tx.home.com...
> How do you stop a class from having subclasses in Python?

def f():
class C:
pass
C()

This is, incidentially, the idiom I had to use extensively to deal with the
lack of nested scoping in Python. More generally, you write a class for
which subclasses don't make sense.

> (And
> what is the supposed benefit of that -- assuming you can find any
> benefits for the singleton DP anywhere, of course).

The benefit of enforcing lack of inheritance? There is none, unless you
believe in the C++/Java way of preventing abuse through access restrictions.
The benefit of singletons? Consider the following module:

# spam.py
def set_variable(name, value):
do_something()

def get_variable(name):
return do_something_else()

def del_variable(name):
do_something_completely_different()

To facilitate easier access to these functions, I introduce the following
wrapper:

class VariableAccess:
def __setattr__(self, name, value):
set_variable(name, value)
def __getattr__(self, name):
return get_variable(name)
def __delattr__(self, name):
return del_variable(name)
variables = VariableAccess()


Now the client can access the revealed variables through a more natural
interface.

> > > A function, _and_ btw
> > > a method too, can access that namespace implicitly or explicitly
> > > [eg via globals()]. It would make no sense for it to be an argument
> > > to the function since it doesn't change at each call -- while the
>
> I note you have signally failed to address this horrid defect in the
> analogy you claim "is there". A method has a global namespace
> _as well_ as access to self as an argument. If functions were to
> access their global namespace though some magic overloading of
> self, how WOULD methods access THEIR global namespace?

Consider the following hypothetical Python-like language:

def f():
print 'spam'

class C:
def f(): # Note lack of 'self'
print 'eggs'
def g():
__instance__.f()
__module__.f()

I'm not sure I like this myself (the __magic__ names are too long, the
result of a 'def' statement depends on context, there's no clear way to
refer to the outer class from a method in an inner class, magically
appearing variables have the potential to cause trouble, and the
'C.f(instance_of_C)' conventions seems to be broken), but at least it's
better than the strawman against which you seem to have been arguing.

> > 'globals()' is syntactically awkward and semantically different from
> > attribute access.
>
> Yes, for special attributes. Just as in C++ namespace qualification is
> syntactically and semantically different from attribute access, too, save
> that the Python situation is simpler.

I'm saying specifically that C++ is right in providing a way to qualify
names as global - no more.

> > # Module spam.py
> > import spam
> > print spam.__dict__
> > print globals()['__dict__']
> >
> > A module importing itself is still the best idiom here.
>
> Your choice. I prefer globals(), myself.

def factorial(n):
if n <= 1:
return 1
else:
return globals()['factorial'](n - 1)

Do you actually write like that, or do you mean "I am too lazy to explitly
qualify global names, explicit-better-than-implicit be damned, so 'globals'
is good enough for me"?

> > > > namespace jam {
> > > > int x = 5;
> > > > void f()
> > > > {
> > > > std::cout << ::jam::x << std::endl;
> > > > }
> > > > }

> A case that will crash and burn as soon as this gets wrapped into


> another namespace (as will no doubt have to happen soon, since
> first thing you know code will have to use this AND another silly
> library using a similarly uninspired namespace name)...? Please.

As a matter of fact, that's another thing Python got wrong. In the absence
of packages (and Python packages are a hack, an ugly one, and not used by
the standard library anyway), module name collisions are inevitable. This
is less of a problem in C++ (although probably for the wrong reason):
namespaces with the same fully qualified name can coexist so long as they
don't contain the same name.

In my own code, I don't use demonstrative namespace names like "jam". But
it doesn't matter anyway. I can afford to (and do) put all of my names in
the global namespace. :-P

> This use of namespaces is NOT good C++ style. Sure, you can
> do it -- and get away with it as long as you're playing with toy
> sized systems, maybe. In real large-scale C++ software, though,
> you had better stick to canonic use. Please see Meyers' Effective
> C++, CDROM edition, for the most elementary and fundamental
> basics. Koenig and Moo in "Ruminations on C++" have quite
> usable material, too. To make a long story short, namespaces
> ARE meant for large-scale software and the top-level namespaces
> had better be unique. You'll use using-declarations to make such
> long unique namespaces usable.

If I was programming large-scale software, that's exactly what I'd do.

> > Lack of lexical scoping is another thing Python got wrong. It causes
code
> > not to work when moved from one scope to another. However, I had not
> > intended to start a general discussion of scoping in programming
> languages.
>
> Yet that's what you did -- because (while making no actual usable
> proposals) you started bemoaning the use of self in methods and/or
> its non-use in module-level functions. These ARE scoping issues,
> after all. Could you really not be aware of that fact?

The comment I made was quite limited in scope, pun intended.

> > I understand very much the value of simplicity and the horror of C++'s
> > complexity. I see inconsitency and over-specialized syntax as the
primary
> > causes, so I attack them in language design whereever I find it - even
in
> > mostly sane languages like Python.
>
> What would the "over-specialized syntax" you are attacking be
> in this case? Please be specific.

In this case, the 'global' statement.

Robin Thomas

unread,
Apr 18, 2001, 7:18:16 PM4/18/01
to kc5...@armored.net, pytho...@python.org
At 01:51 PM 4/18/01 -0700, Samuel A. Falvo II wrote:
>Because they expose an interface, a module can be treated as an instance of
>a class defined by the global definitions of that module (it's a recursive
>definition, and this is why other dynamic OO environments have the concept
>of "meta-classes" as well as classes, so as to break this recursion).

You're smashing into the type/class dichotomy again. Python types are not
classes, and if you wish to mush them together in your imagination, you can
waste a lot of your time before discovering, once again, that they really
are different.

Lots of people on this list, myself included, wish types and classes to be
unified, or at least brought much more closely together, in a future
version of Python.

Our preferred implementation method is to wish really really hard. When we
get frustrated from all that wishing, we make wild assertions and pick
fights to blow off steam.

If you want metaclasses, you have them, in a wry Pythonic way:

http://www.python.org/doc/essays/metaclasses/


--
robi...@yahoo.com


_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com

s71...@student.gu.edu.au

unread,
Apr 19, 2001, 6:36:48 AM4/19/01
to
Dave LeBlanc wrote:

> I was going to mention super, but given the multiple inheritance
> nature of Python, it wouldn't work.

If you want super functionality, a poster a year or so ago, submitted
this little hack for a situation where he wanted to use a derived class
with multiple base classes, but without having to retype dozens of lines
of code.

class friendly:
def __init__(self):
print "Hello"
class friendlier(friendly):
def __super(self):
return friendly
def __init__(self, name):
self.__super().__init__(self)
print name

As long as you've only got single inheritance, or are only interested in
the first class, you can automate it as follows:

class friendlier(friendly):
def __super(self):
return self.__class__.__bases__[0]

Useful in some situations,

Joal Heagney/AncientHart

Jeremy Hylton

unread,
Apr 19, 2001, 12:25:12 AM4/19/01
to Rainer Deyke, pytho...@python.org
>>>>> "RD" == Rainer Deyke <ro...@rainerdeyke.com> writes:

RD> def f():
RD> class C:
RD> pass
RD> C()

RD> This is, incidentially, the idiom I had to use extensively to
RD> deal with the lack of nested scoping in Python. More generally,
RD> you write a class for which subclasses don't make sense.

It's former lack of nested scopes, I believe ;-).

Jeremy


pi...@cs.uu.nl

unread,
Apr 19, 2001, 6:52:50 AM4/19/01
to
>>>>> Luke <flo...@netplus.net> (L) writes:

L> Java's system works just fine. It is assumed when you are writing a
L> class, that a variable is part of that class. It makes more sense. After
L> all why wouldn't you assume first that a variable that is part of a
L> class belongs to that class. If you are dumb and want to put an
L> identical variable in a local scope in a function, for example, then you
L> use this.foo to distinguish. Java is more logical IMHO

But Java has variable declarations, while Python doesn't. So in Java the
compiler can find out where a variable belongs. In Python you can create
instance variables at runtime, so the compiler can't know it is an instance
variable.

E.g.

class A:
def method(self, p):
x = p
return x


a = A()
a.method(1)
a.x=5
a.method(2)

Steve Holden

unread,
Apr 19, 2001, 8:27:29 AM4/19/01
to
"Jeremy Hylton" <jer...@digicool.com> wrote in message
news:mailman.987654387...@python.org...
Perhaps you meant "before its implementation of nested scopes in the
__future__"?

regards
Steve

Alex Martelli

unread,
Apr 19, 2001, 12:42:11 PM4/19/01
to
"Rainer Deyke" <ro...@rainerdeyke.com> wrote in message
news:vQpD6.47756$J%5.158...@news2.rdc2.tx.home.com...
[snip]

> "Alex Martelli" <ale...@yahoo.com> wrote in message
> news:9bkvi...@news1.newsguy.com...
> > "Rainer Deyke" <ro...@rainerdeyke.com> wrote in message
> > news:OLlD6.46125$J%5.153...@news2.rdc2.tx.home.com...
> > How do you stop a class from having subclasses in Python?
>
> def f():
> class C:
> pass
> C()

Ok, it's now clearer what you mean, thanks. It doesn't
STOP somebody sufficiently determined from subclassing
it, of course:

class OhYeah(f().__class__):
pass

but it does provide a rather good hint that "being
subclassed" is not the class's design intention:-).


> This is, incidentially, the idiom I had to use extensively to deal with
the
> lack of nested scoping in Python. More generally, you write a class for

How does a local class help you there in ways nested
scoping will make obsolete? Sounds interesting.


> > what is the supposed benefit of that -- assuming you can find any
> > benefits for the singleton DP anywhere, of course).
>
> The benefit of enforcing lack of inheritance? There is none, unless you
> believe in the C++/Java way of preventing abuse through access
restrictions.

Java does enforce that, but in Python you get no "abuse
protection" (and no access restrictions) unless via
restricted execution, bastions &c (and C++, notoriously,
only "makes believe" any security accrues -- actually the
language standard makes it pretty clear that no abuse is
really prevented, but few practitioners seem to get it).

> The benefit of singletons? Consider the following module:
>
> # spam.py
> def set_variable(name, value):
> do_something()
>
> def get_variable(name):
> return do_something_else()
>
> def del_variable(name):
> do_something_completely_different()
>
> To facilitate easier access to these functions, I introduce the following
> wrapper:
>
> class VariableAccess:
> def __setattr__(self, name, value):
> set_variable(name, value)
> def __getattr__(self, name):
> return get_variable(name)
> def __delattr__(self, name):
> return del_variable(name)
> variables = VariableAccess()
>
>
> Now the client can access the revealed variables through a more natural
> interface.

Nice -- a specifically Pythonic benefit. Of course, it's no
problem if VariableAccess gets multiply instantiated, so I
would consider this an example of the pattern "Featherweight"
(a class whose instances share all state) rather than one of
the pattern "Singleton" (a class that is protected against
being multiply instantiated), and I like FW as much as I
dislike Singleton, so there's still no benefit to the singleton
design pattern, but that's another issue.


> Consider the following hypothetical Python-like language:
>
> def f():
> print 'spam'
>
> class C:
> def f(): # Note lack of 'self'
> print 'eggs'
> def g():
> __instance__.f()
> __module__.f()
>
> I'm not sure I like this myself (the __magic__ names are too long, the
> result of a 'def' statement depends on context, there's no clear way to
> refer to the outer class from a method in an inner class, magically
> appearing variables have the potential to cause trouble, and the
> 'C.f(instance_of_C)' conventions seems to be broken), but at least it's
> better than the strawman against which you seem to have been arguing.

Actually, I think _this_ is "a strawman proposal" -- one with some
admitted defects but that at some level realizes design intentions.
Earlier, I saw complaints but no pointer to resolving them.

Thanks for posting it at last. I fully agree with all of your
criticisms, and furthermore don't see how this will support the
useful idiom of assigning an existing function to serve as a method,
but then, pointing out such issues _IS_ a strawman proposal's role.

I do see one nugget here -- allowing access to a module object
through one of its own magic attributes may indeed be handier
than using globals(), sys.modules[__name__], and other existing
idioms. The 'reference loop' it implies may be less terrible
today (what with weak references, garbage collection, etc) than
it may once have appeared. Having each module object possess
a __module__ attribute that references the object itself seems
feasible, if the need to use that object is indeed frequent.

A somewhat related issue is somehow getting easy access to the
function object from that function's code -- particularly likely
to be interesting now that function objects have arbitrary
attributes. Presumably harder as the __function__ (or
whatever) would have to be stuck in (the locals...?). Just
an aside, anyway.


> I'm saying specifically that C++ is right in providing a way to qualify
> names as global - no more.

OK, I accept that's what you intended to say right from the
start. Now, "global" in C++ means "global across all sources"
rather than "specific to this source". Object specific to
this module would be in the unnamed namespace (since the
use of 'static' for that is [informally speaking only, I
believe] deprecated in C++) and thus non-qualifiable; other
(non-unnamed) namespaces are shared across sources. Are
you expressing admiration for THIS trait of C++? Or do you
actually wish to keep things Pythonically simple and is
the C++ reference some sort of red herring? It's starting
to look that way to me.


> def factorial(n):
> if n <= 1:
> return 1
> else:
> return globals()['factorial'](n - 1)
>
> Do you actually write like that, or do you mean "I am too lazy to explitly
> qualify global names, explicit-better-than-implicit be damned, so
'globals'
> is good enough for me"?

I don't write like that, although my lack of qualification
for (module) globals stems from desire for simplicity and
clarity, rather than from laziness. I do use globals() in
those rare instances where I feel I need it -- only one
that comes to mind readily is a function which is documented
to have a parameter named 'feep' (can't change that without
breaking client code) living in a module that is also
documented to have an attribute named 'feep' (ditto); then,
from within that function, accessing globals() is one
possibility if the global 'feep' is needed (there are
others, of course, such as a module-level
_feep = feep
to provide handier internal access).

You _have_ convinced me that, if every module had a magic
attribute __module__ returning itself, some cases of such
explicit-to-global access would be facilitated wrt the
present situation. And, although such need is rare in
my code, I have no basis for asserting that it would be
also rare in others' -- e.g., maybe somebody _IS_ designing
libraries where module-level attributes and function
optional arguments systematically share names, and has
data to show that this makes his clients' life easier.


> > What would the "over-specialized syntax" you are attacking be
> > in this case? Please be specific.
>
> In this case, the 'global' statement.

I think I see -- if we had __module__, then the global
statement might eventually be deprecated in favor of
suggesting the idiom
__module__.feep = 23
to rebind globals, rather than the present
global feep
feep = 23

An interesting possibility, and one worth thinking about
(I'm not sure I like it, but I'm also far from sure I
dislike it). Discussion would have been shorter if you
had indicated this a TAD more explicitly from the start
rather than "deprecating self", lauding C++, etc, but
I guess that's just another explicit/implicit thing:-).
It _does_ look "more pythonic" than 'global', in a sense.

Why don't you do a PEP on this? It seems definitely
worthwhile to discuss, and I don't think it will get
the attention it deserves when buried at the end of
a long post in a subthread of a long thread with a
title not very clearly related to it (though I've
tried to change subject in case this does help it get
read:-).


Alex

Ben Wolfson

unread,
Apr 19, 2001, 6:11:07 PM4/19/01
to
In article <vQpD6.47756$J%5.158...@news2.rdc2.tx.home.com>, "Rainer
Deyke" <ro...@rainerdeyke.com> wrote:

> "Alex Martelli" <ale...@yahoo.com> wrote in message
> news:9bkvi...@news1.newsguy.com...
>> "Rainer Deyke" <ro...@rainerdeyke.com> wrote in message
>> news:OLlD6.46125$J%5.153...@news2.rdc2.tx.home.com... How do you stop
>> a class from having subclasses in Python?
>
> def f():
> class C:
> pass
> C()

>>> from klass import klass
>>> def get_atuple(self):
return self.atuple

>>> def init(self, tup):
self.atuple = tup

>>> def set_atuple(self, tup):
self.atuple = tup

>>> TupleHaver = klass({}, {'__init__':init, 'get_atuple':get_atuple,
'set_atuple':set_atuple}) t = TupleHaver((1,2,'hi'))
>>> t.get_atuple()
(1, 2, 'hi')
>>> t.set_atuple(('la la', 'la'))
>>> t.get_atuple()
('la la', 'la')

### part of klass.py

def klass(static_var_dict, methdict):
def make(*initv, **initk):
inst = lambda: None
m = {}
for k in methdict.keys():
m[k] = fako(methdict[k], inst)
inst.func_dict = m
inst.func_dict.update(static_var_dict) m.get('__init__', lambda\
*a, **k: None)(*initv, **initk)
return inst
return make

def fako(func, inst):
return lambda *a, **k: func( *((inst,)+a), **k)


--
Barnabas T. Rumjuggler
Thou hast been called, O Sleep! The friend of woe,
But 'tis the happy who have called thee so.
-- Robert Southey

David C. Ullrich

unread,
Apr 18, 2001, 11:50:23 AM4/18/01
to
On Wed, 18 Apr 2001 10:59:09 +0200, "Alex Martelli"
<ale...@yahoo.com> wrote:

>"Dave LeBlanc" <whi...@oz.net> wrote in message

>news:9bji5k$417$0...@216.39.170.247...


>> Since self is used for every method of every class, isn't it a bit
>> redundant?
>

>Not really. Explicit is better than implicit.
>

>> I don't know of another OO language that makes you manually
>> carry around the "this"/"self" pointer/reference...
>

>Modula-3, for example (I believe 'self' is a reserved word

>there; in Python, it's "just" a 'universal' convention).

Almost universal. I was surprised at first to see some guy's

def __add__(x,y):
return something_involving(x,y);

looked at first like he wasn't aware of this universal convention.
Then I decided that in the sort of context where this was used
his notation made a lot more sense.

(And of course an implicit self makes less sense than anything
here...)


Rainer Deyke

unread,
Apr 20, 2001, 12:45:55 AM4/20/01
to
"Alex Martelli" <ale...@yahoo.com> wrote in message
news:9bn4g...@news1.newsguy.com...

> "Rainer Deyke" <ro...@rainerdeyke.com> wrote in message
> news:vQpD6.47756$J%5.158...@news2.rdc2.tx.home.com...
> [snip]
> > def f():
> > class C:
> > pass
> > C()
>
> Ok, it's now clearer what you mean, thanks. It doesn't
> STOP somebody sufficiently determined from subclassing
> it, of course:
>
> class OhYeah(f().__class__):
> pass

Actually I'm not even returning an instance in my example, so even that
isn't possible.

> but it does provide a rather good hint that "being
> subclassed" is not the class's design intention:-).

> > This is, incidentially, the idiom I had to use extensively to deal with
> the
> > lack of nested scoping in Python. More generally, you write a class for
>
> How does a local class help you there in ways nested
> scoping will make obsolete? Sounds interesting.

def render(draw_fn):
gc = get_gc()
draw_fn(gc)

def render_text(text):
class Text:
def __init__(self, text):
self.text = text
def draw(gc):
gc.draw_text(self.text)
t = Text(text)
render(t.draw)

In this case I could have used the default argument hack, but that isn't
generally applicable (think *args, **kwargs).

There is no reason for multiply instantiating 'VariableAccess' because the
defining module provides one instance and every instance other instance is
identical in state and behavior. Whether you call this a "Singleton" or a
"Featherweight" or even "Gorak, destroyer of worlds" is all the same to me.

> > Consider the following hypothetical Python-like language:
> >
> > def f():
> > print 'spam'
> >
> > class C:
> > def f(): # Note lack of 'self'
> > print 'eggs'
> > def g():
> > __instance__.f()
> > __module__.f()
> >
> > I'm not sure I like this myself (the __magic__ names are too long, the
> > result of a 'def' statement depends on context, there's no clear way to
> > refer to the outer class from a method in an inner class, magically
> > appearing variables have the potential to cause trouble, and the
> > 'C.f(instance_of_C)' conventions seems to be broken), but at least it's
> > better than the strawman against which you seem to have been arguing.
>
> Actually, I think _this_ is "a strawman proposal" -- one with some
> admitted defects but that at some level realizes design intentions.
> Earlier, I saw complaints but no pointer to resolving them.

My goal wasn't to change Python, but to discuss a perceived flaw in Python
which later generations of language designers would then be able to avoid
(or alternately to be convinced that the inconsistency is a good idea for
pragmatic reasons).

> Thanks for posting it at last. I fully agree with all of your
> criticisms, and furthermore don't see how this will support the
> useful idiom of assigning an existing function to serve as a method,

Given this:

def f(x):
do_something_width(x)

Instead of writing this:

class C:
do_f = f

Write this:

class C:
def do_f():
__module__.f(__instance__) # Where '__module__.' might be optional.

This is assuming that you want the instance as first argument. There are
times when you don't; see 'VariableAccessor' above.

> but then, pointing out such issues _IS_ a strawman proposal's role.
>
> I do see one nugget here -- allowing access to a module object
> through one of its own magic attributes may indeed be handier
> than using globals(), sys.modules[__name__], and other existing
> idioms. The 'reference loop' it implies may be less terrible
> today (what with weak references, garbage collection, etc) than
> it may once have appeared. Having each module object possess
> a __module__ attribute that references the object itself seems
> feasible, if the need to use that object is indeed frequent.
>
> A somewhat related issue is somehow getting easy access to the
> function object from that function's code -- particularly likely
> to be interesting now that function objects have arbitrary
> attributes. Presumably harder as the __function__ (or
> whatever) would have to be stuck in (the locals...?). Just
> an aside, anyway.

'__function__' could be treated similarily to default arguments. I don't
see the problem.

> > I'm saying specifically that C++ is right in providing a way to qualify
> > names as global - no more.
>
> OK, I accept that's what you intended to say right from the
> start. Now, "global" in C++ means "global across all sources"
> rather than "specific to this source". Object specific to
> this module would be in the unnamed namespace (since the
> use of 'static' for that is [informally speaking only, I
> believe] deprecated in C++) and thus non-qualifiable; other
> (non-unnamed) namespaces are shared across sources. Are
> you expressing admiration for THIS trait of C++?

No. I see a certain advantage to C++'s decoupling of file and namespace,
but I am neither talking about it here, nor do I wish it upon Python.

> Or do you
> actually wish to keep things Pythonically simple and is
> the C++ reference some sort of red herring? It's starting
> to look that way to me.

Python is more than complex enough for me.

Martin von Loewis

unread,
Apr 20, 2001, 2:18:27 AM4/20/01
to
whi...@oz.net (Dave LeBlanc) writes:

> Smalltalk never requres the declaration of self as an arguement to a
> method. self is only used to identify the target (variable or method
> invocation) as being local to the caller (i.e. in it's own class
> scope). It's been awhile, so I don't recall if it's mandatory in that
> context or not.

It's been a while for me as well, but: I thought it required self for
message sent to itself, and required not to use self for instance
variables:

name
"Answer the name of the file identified by the receiver"
^name

Regards,
Martin

Alex Martelli

unread,
Apr 20, 2001, 8:27:37 AM4/20/01
to
"Rainer Deyke" <ro...@rainerdeyke.com> wrote in message
news:7aPD6.58066$J%5.192...@news2.rdc2.tx.home.com...

> "Alex Martelli" <ale...@yahoo.com> wrote in message
> news:9bn4g...@news1.newsguy.com...
> > "Rainer Deyke" <ro...@rainerdeyke.com> wrote in message
> > news:vQpD6.47756$J%5.158...@news2.rdc2.tx.home.com...
> > [snip]
> > > def f():
> > > class C:
> > > pass
> > > C()
> >
> > Ok, it's now clearer what you mean, thanks. It doesn't
> > STOP somebody sufficiently determined from subclassing
> > it, of course:
> >
> > class OhYeah(f().__class__):
> > pass
>
> Actually I'm not even returning an instance in my example, so even that
> isn't possible.

True -- you're instancing but not returning it; I had made
a "think-o" and read a "return" that wasn't there. If no
instances of the class (as well as the class object itself,
method objects, etc) survive the function-execution nor
escape its confines, you _can_ indeed fully control the
use of the class.


> > but it does provide a rather good hint that "being
> > subclassed" is not the class's design intention:-).
>
> > > This is, incidentially, the idiom I had to use extensively to deal
with
> > the
> > > lack of nested scoping in Python. More generally, you write a class
for
> >
> > How does a local class help you there in ways nested
> > scoping will make obsolete? Sounds interesting.
>
> def render(draw_fn):
> gc = get_gc()
> draw_fn(gc)
>
> def render_text(text):
> class Text:
> def __init__(self, text):
> self.text = text
> def draw(gc):
> gc.draw_text(self.text)

I think you mean "def draw(self, gc):" here, right? (Given
that this is meant to be current-Python code).

> t = Text(text)
> render(t.draw)
>
> In this case I could have used the default argument hack, but that isn't
> generally applicable (think *args, **kwargs).

True, if you can't 'reserve' any name (need to accept all as **kwargs)
you can't use default argument values to bind state, so a local class
is a way to get complete generality while a local function will indeed
suffice when scopes nest. Thanks for the example. (I'll even avoid
pointing out that, since a bound-method DOES "escape the confines" of
function render_text, inheritance from the local Text class does
become _possible_ again -- the render function could be changed to
one that defines a class inheriting from draw_fn.im_class -- as this
is so obviously outside of design intent that only a fully paranoid
system could expend effort to enforce things here:-).


> > Nice -- a specifically Pythonic benefit. Of course, it's no
> > problem if VariableAccess gets multiply instantiated, so I
> > would consider this an example of the pattern "Featherweight"
> > (a class whose instances share all state) rather than one of
> > the pattern "Singleton" (a class that is protected against
> > being multiply instantiated), and I like FW as much as I
> > dislike Singleton, so there's still no benefit to the singleton
> > design pattern, but that's another issue.
>
> There is no reason for multiply instantiating 'VariableAccess' because the

No special reason to do so, no special reason to avoid doing
so. That is fine with me and doesn't match the description
of the "Singleton" design pattern.

> defining module provides one instance and every instance other instance is
> identical in state and behavior. Whether you call this a "Singleton" or a
> "Featherweight" or even "Gorak, destroyer of worlds" is all the same to
me.

Not to me, nor to most readers, since design patterns' _names_
are an important characteristic -- the "primary key" used to
retrieve (from memory, a book, etc etc) the various things that
make up the pattern -- what forces it resolves, how, etc. The
Singleton DP goes to some effort to avoid multiple instantiation
and relies on that; I've long thought that expending effort that
is not greater, and in fact is often lesser, to ensure that
multiple instantiations can occur innocuously (by sharing state
among potentially-multiple instances), makes for better design
patterns (albeit the catchy "Singleton" name makes it perhaps
the most popular and well-known Gof4 DP). So I'm always on the
lookout for situations where the actual forces DO make Singleton
preferable to FeatherWeight -- haven't found any so far.

That there exist design situations where a single copy of a
certain "state" is desirable, is hardly in question -- that IS
a force that comes up again and again. The issue is how to
best resolve it, and the other forces that accompany it in
various use cases.


> > > Consider the following hypothetical Python-like language:
> > >
> > > def f():
> > > print 'spam'
> > >
> > > class C:
> > > def f(): # Note lack of 'self'
> > > print 'eggs'
> > > def g():
> > > __instance__.f()
> > > __module__.f()
> > >
> > > I'm not sure I like this myself (the __magic__ names are too long, the
> > > result of a 'def' statement depends on context, there's no clear way
to
> > > refer to the outer class from a method in an inner class, magically
> > > appearing variables have the potential to cause trouble, and the
> > > 'C.f(instance_of_C)' conventions seems to be broken), but at least
it's
> > > better than the strawman against which you seem to have been arguing.
> >
> > Actually, I think _this_ is "a strawman proposal" -- one with some
> > admitted defects but that at some level realizes design intentions.
> > Earlier, I saw complaints but no pointer to resolving them.
>
> My goal wasn't to change Python, but to discuss a perceived flaw in Python
> which later generations of language designers would then be able to avoid
> (or alternately to be convinced that the inconsistency is a good idea for
> pragmatic reasons).

Your "strawman proposal" doesn't seem to show up any inconsistency in
Python as it stands. It _does_, to me at least, suggest a possible
lack (specifically that of a __module__ magicnamed attribute in each
module object, referring [maybe weakly, or whatever] to the module
object itself, to avoid having to import, check sys.modules, etc --
assuming for the sake of argument that the need for code in a module
to refer to the module object IS a frequent enough one to warrant it).


> > Thanks for posting it at last. I fully agree with all of your
> > criticisms, and furthermore don't see how this will support the
> > useful idiom of assigning an existing function to serve as a method,
>
> Given this:
>
> def f(x):
> do_something_width(x)
>
> Instead of writing this:
>
> class C:
> do_f = f
>
> Write this:
>
> class C:
> def do_f():
> __module__.f(__instance__) # Where '__module__.' might be optional.

Right -- it doesn't support the existing idiom, so you have to
code around it with explicit delegation. Enriching an existing
class-object from outside the class's body seems even more of
a problem -- current "C.do_f=f" becomes...? The "def depends
on context" defect that you noticed seems to hurt here.


> This is assuming that you want the instance as first argument. There are
> times when you don't; see 'VariableAccessor' above.

Yes, some people do keep clamoring for "class methods", and
this strawman might support them as it enables methods to
be (e.g.) without arguments. Some would no doubt prefer to
have a simpler "class method" idiom even at the cost of
totally losing the "add a function as a method" one -- and
of even deeper black magic than the current type mutation
(function to unbound method).


> > A somewhat related issue is somehow getting easy access to the
> > function object from that function's code -- particularly likely
> > to be interesting now that function objects have arbitrary
> > attributes. Presumably harder as the __function__ (or
> > whatever) would have to be stuck in (the locals...?). Just
> > an aside, anyway.
>
> '__function__' could be treated similarily to default arguments. I don't
> see the problem.

Placing '__function__' in the local namespace of every single
function is a higher cost than placing '__module__' in the
namespace of every module for the very simple reason that
there are relatively few modules, created pretty rarely, and
a LOT of functions, some of which are created more often (in
a style using a lot of local functions). The reference circle
that gets created may not be as simple and thus easily handled
as " anymodule.__dict__['__module__'] is anymodule " -- it
would presumably be " anyfunc.func_defaults[0] is anyfunc "
(but would 0 be appropriate here?) _plus_ something like
" anyfunc.func_code.co_varnames[ ??what?? ] == '__function__' "
where I guess ??what?? is one more than the actual number
of non-default function parameters. The implementation does
seem more complex to me than the crystal-simplicity of __module__.
Maybe the newer mechanisms put in place to support nested
scopes may happen to make this easier -- haven't looked much
at them yet; or maybe there _are_ better places for this than
func_defaults anyway. "Presumable harder" (than __module__)
seems a fair assessment to me.


> > > I'm saying specifically that C++ is right in providing a way to
qualify
> > > names as global - no more.
> >
> > OK, I accept that's what you intended to say right from the
> > start. Now, "global" in C++ means "global across all sources"
> > rather than "specific to this source". Object specific to
> > this module would be in the unnamed namespace (since the
> > use of 'static' for that is [informally speaking only, I
> > believe] deprecated in C++) and thus non-qualifiable; other
> > (non-unnamed) namespaces are shared across sources. Are
> > you expressing admiration for THIS trait of C++?
>
> No. I see a certain advantage to C++'s decoupling of file and namespace,
> but I am neither talking about it here, nor do I wish it upon Python.

OK. Having worked extensively with both languages which
couple sourcefiles and namespaces/modules (Python, Java,
etc) and others that decouple them (C, C++, Fortran) I
strongly prefer the former approach, but if this aspect
of the discussion doesn't touch Python then we'd better
drop it, I guess, as there are so many other subthreads
here that ARE Python-relevant anyway.


> > Or do you
> > actually wish to keep things Pythonically simple and is
> > the C++ reference some sort of red herring? It's starting
> > to look that way to me.
>
> Python is more than complex enough for me.

So how would __module__ and __istance__ and __function__
and all other such additions REDUCE its complexity that
you perceive?


Alex

Rainer Deyke

unread,
Apr 20, 2001, 1:14:46 PM4/20/01
to
"Alex Martelli" <ale...@yahoo.com> wrote in message
news:9bp9v...@news1.newsguy.com...

> "Rainer Deyke" <ro...@rainerdeyke.com> wrote in message
> > def render(draw_fn):
> > gc = get_gc()
> > draw_fn(gc)
> >
> > def render_text(text):
> > class Text:
> > def __init__(self, text):
> > self.text = text
> > def draw(gc):
> > gc.draw_text(self.text)
>
> I think you mean "def draw(self, gc):" here, right? (Given
> that this is meant to be current-Python code).

Yes. I still forget to explicitly list 'self' as an argument, even after
months of Python use.

> > defining module provides one instance and every instance other instance
is
> > identical in state and behavior. Whether you call this a "Singleton" or
a
> > "Featherweight" or even "Gorak, destroyer of worlds" is all the same to
> me.
>
> Not to me, nor to most readers, since design patterns' _names_
> are an important characteristic -- the "primary key" used to
> retrieve (from memory, a book, etc etc) the various things that
> make up the pattern -- what forces it resolves, how, etc. The
> Singleton DP goes to some effort to avoid multiple instantiation
> and relies on that; I've long thought that expending effort that
> is not greater, and in fact is often lesser, to ensure that
> multiple instantiations can occur innocuously (by sharing state
> among potentially-multiple instances), makes for better design
> patterns (albeit the catchy "Singleton" name makes it perhaps
> the most popular and well-known Gof4 DP). So I'm always on the
> lookout for situations where the actual forces DO make Singleton
> preferable to FeatherWeight -- haven't found any so far.

Just as I can use the term "command" to refer something different from the
Command design pattern (note different capitalization), I generally use the
word singleton to refer to something that is not necessarily implemented
through the Singleton design pattern.

> That there exist design situations where a single copy of a
> certain "state" is desirable, is hardly in question -- that IS
> a force that comes up again and again. The issue is how to
> best resolve it, and the other forces that accompany it in
> various use cases.

What generic word would you use to refer to an object that encapsulates
program-wide unique state?

> > My goal wasn't to change Python, but to discuss a perceived flaw in
Python
> > which later generations of language designers would then be able to
avoid
> > (or alternately to be convinced that the inconsistency is a good idea
for
> > pragmatic reasons).
>
> Your "strawman proposal" doesn't seem to show up any inconsistency in
> Python as it stands.

I consider classes/instances a special case of namespaces: one which allows
(multiple) instantiation and inheritance. In actual pratice not all of the
classes I design are designed for multiple instantiation, or instantiation
at all for that matter. What I would like to see is a separation of
concerns ("Does this namespace have __special__ attributes for operator
overloading?" inpdependent from "Does this namespace require
instantiation?") followed by a culling of irrelevant features ("Don't want
operator overloading? Don't name your function '__add__' then."). The
resulting programming language might look something like this:

namespace A: # Create a named unique object
pass
namespace B(A): # Similar to 'from ... import', but done through linking
# instead of copying
class C(A): # 'class' = namespace that requires/supports instantiation
# class inherits from namespace => functions in namespace
# are treated as "static" functions
pass
namespace D(C()): # namespace inherits from instance of class
pass


The module itself would be a 'namespace' object. Overall, I think this has
the potential of creating a much simpler and more regular language.
Separate keywords for 'class' and 'namespace' might even turn out to be
unnecessary.

My pointing out the inconsistency between methods and free functions was in
the spirit of a scheme similar to the one above. I might turn out to be
wrong about the inconsistency, though: I haven't thought this unification
scheme completely through yet.

> > Given this:
> >
> > def f(x):
> > do_something_width(x)
> >
> > Instead of writing this:
> >
> > class C:
> > do_f = f
> >
> > Write this:
> >
> > class C:
> > def do_f():
> > __module__.f(__instance__) # Where '__module__.' might be optional.
>
> Right -- it doesn't support the existing idiom, so you have to
> code around it with explicit delegation. Enriching an existing
> class-object from outside the class's body seems even more of
> a problem -- current "C.do_f=f" becomes...? The "def depends
> on context" defect that you noticed seems to hurt here.

I really don't like to have 'def' depend on context, but in practice it
already does. In Python as it is, it is possible to turn free functions
into methods but not the other way around. This is another thing that bears
thinking about, especially in the light of the unification scheme above
(which would break all backwards compatibility anyways).

> > > Or do you
> > > actually wish to keep things Pythonically simple and is
> > > the C++ reference some sort of red herring? It's starting
> > > to look that way to me.
> >
> > Python is more than complex enough for me.
>
> So how would __module__ and __istance__ and __function__
> and all other such additions REDUCE its complexity that
> you perceive?

See above for my Grand Unification Scheme. '__module__', at least, makes
'global' redundant. As I stated in another thread, sometimes you need to
add new features before you can remove old ones. '__module__' seems simpler
to me than the one-and-only non-executable statement in Python.

Alex Martelli

unread,
Apr 20, 2001, 5:24:47 PM4/20/01
to
"Rainer Deyke" <ro...@rainerdeyke.com> wrote in message
news:a8_D6.60935$J%5.204...@news2.rdc2.tx.home.com...
[snip]

> Just as I can use the term "command" to refer something different from the
> Command design pattern (note different capitalization), I generally use
the
> word singleton to refer to something that is not necessarily implemented
> through the Singleton design pattern.

Makes sense, which is why I asked very specifically, when you
mentioned singletons, whether you had examples where you
found the Singleton design pattern best. Apparently your
answer was not to the question I asked.


> > That there exist design situations where a single copy of a
> > certain "state" is desirable, is hardly in question -- that IS
> > a force that comes up again and again. The issue is how to
> > best resolve it, and the other forces that accompany it in
> > various use cases.
>
> What generic word would you use to refer to an object that encapsulates
> program-wide unique state?

As it happens, in my favourite (free-time) application area, I had
better avoid naming such object 'singletons' any more than I could
name others 'doubles', 'diamonds' or 'squeezes' -- these are all
important words and concepts in contract bridge (and, some of
them, in other games, too -- but bridge is my field).

Apart from application areas -- in maths, a singleton is a set with
a single member... it's not that member (and the distinction is
important). If one looks at a _class_ as somehow equivalent to
the set of its instances, then calling the *class* 'a singleton' may
make sense, but calling the *instance* 'a singleton' would not.


> > > Python is more than complex enough for me.
> >
> > So how would __module__ and __istance__ and __function__
> > and all other such additions REDUCE its complexity that
> > you perceive?
>
> See above for my Grand Unification Scheme. '__module__', at least, makes
> 'global' redundant. As I stated in another thread, sometimes you need to
> add new features before you can remove old ones. '__module__' seems
simpler
> to me than the one-and-only non-executable statement in Python.

If modifying globals from inside a function is meant to be a rare
thing, then I agree with you that using "__module__.x=y" &c for
such modifications (rather than "global x" followed by "x=y") may
be perfectly acceptable. The global statement does cater better
for a style in which such "rebinding of globals" from within a
function come "in clusters" -- many functions may not need to
do any such binding, but those that do may need to bind more
than one global or at least bind a global in several places, e.g.

def example():
global x,y,z
if x>0:
x=y=z=23
elif y<z:
x=y=z=34

is already substantially more readable than an equivalent
using __module__ six times.


'global' does (in my modest experience) give some problem
to some students, typically coming out as expressions of
astonisment that some equivalent of

x=23
def f():
print x
x=45
print x

fails. This empirical observation does lend some support to
your thesis. However, I wonder if having the 'fix' be changing
the assignment to "__module__.x=45", rather than inserting
a "global x", would do all that much good in this regard.


Alex

Tim Hochberg

unread,
Apr 20, 2001, 6:45:40 PM4/20/01
to

"Alex Martelli" <ale...@yahoo.com> wrote in message
news:9bq9i...@news1.newsguy.com...

[SNAP]

> If modifying globals from inside a function is meant to be a rare
> thing, then I agree with you that using "__module__.x=y" &c for
> such modifications (rather than "global x" followed by "x=y") may
> be perfectly acceptable. The global statement does cater better
> for a style in which such "rebinding of globals" from within a
> function come "in clusters" -- many functions may not need to
> do any such binding, but those that do may need to bind more
> than one global or at least bind a global in several places, e.g.
>
> def example():
> global x,y,z
> if x>0:
> x=y=z=23
> elif y<z:
> x=y=z=34
>
> is already substantially more readable than an equivalent
> using __module__ six times.

In this case, might I suggest the following (hypothetical) idiom:

def example2():
m = __module__
if x > 0:
m.x = m.y = m.z = 23
elif y < z:
m.x = m.y = m.z = 34

[SNAP]

-tim


Rainer Deyke

unread,
Apr 20, 2001, 8:10:34 PM4/20/01
to
"Alex Martelli" <ale...@yahoo.com> wrote in message
news:9bq9i...@news1.newsguy.com...

> "Rainer Deyke" <ro...@rainerdeyke.com> wrote in message
> news:a8_D6.60935$J%5.204...@news2.rdc2.tx.home.com...
> [snip]
> > Just as I can use the term "command" to refer something different from
the
> > Command design pattern (note different capitalization), I generally use
> the
> > word singleton to refer to something that is not necessarily implemented
> > through the Singleton design pattern.
>
> Makes sense, which is why I asked very specifically, when you
> mentioned singletons, whether you had examples where you
> found the Singleton design pattern best. Apparently your
> answer was not to the question I asked.

To answer your question, I have yet to use either the Singleton pattern or
the Flyweight pattern exactly as described in Design Patterns. To
enapsulate global state I use global variables (or, in C++, static variables
of functions). Sometimes these variables require a new class, usually they
don't.

> > What generic word would you use to refer to an object that encapsulates
> > program-wide unique state?
>
> As it happens, in my favourite (free-time) application area, I had
> better avoid naming such object 'singletons' any more than I could
> name others 'doubles', 'diamonds' or 'squeezes' -- these are all
> important words and concepts in contract bridge (and, some of
> them, in other games, too -- but bridge is my field).
>
> Apart from application areas -- in maths, a singleton is a set with
> a single member... it's not that member (and the distinction is
> important). If one looks at a _class_ as somehow equivalent to
> the set of its instances, then calling the *class* 'a singleton' may
> make sense, but calling the *instance* 'a singleton' would not.

This does not answer my question.

> > See above for my Grand Unification Scheme. '__module__', at least,
makes
> > 'global' redundant. As I stated in another thread, sometimes you need
to
> > add new features before you can remove old ones. '__module__' seems
> simpler
> > to me than the one-and-only non-executable statement in Python.
>
> If modifying globals from inside a function is meant to be a rare
> thing, then I agree with you that using "__module__.x=y" &c for
> such modifications (rather than "global x" followed by "x=y") may
> be perfectly acceptable. The global statement does cater better
> for a style in which such "rebinding of globals" from within a
> function come "in clusters" -- many functions may not need to
> do any such binding, but those that do may need to bind more
> than one global or at least bind a global in several places, e.g.
>
> def example():
> global x,y,z
> if x>0:
> x=y=z=23
> elif y<z:
> x=y=z=34
>
> is already substantially more readable than an equivalent
> using __module__ six times.

The same argument could apply to methods:

def example(self):
if self.x > 0:
self.x = self.y = self.z = 23
elif self.y < self.z:
self.x = self.y = self.z = 34

vs.

def example(self):
instance x, y, z
if x > 0:
x = y = z = 23
elif y < z:
x = y = z = 34


I find the former quite readable, but that's just me. If you recall, I was
arguing for consistency, not necessarily for any specific approach.

0 new messages