Why no lexical scoping for a method within a class?

2008-12-17 Thread rdmurray
Quoth walterbyrd :
> For a language as well structured as Python, this seems somewhat
> sloppy, and inconsistant.  Or is there some good reason for this?

Yes.  It's called Object Oriented Programming.

> Here is what I mean:
> 
> def a():
> x = 99
> print x
> 
> def b():
> print x
> 
> a()
> b() # raises an exception because x is not defined.
> 
> However in the methods are within a class, the scoping seems to work
> differently.
> 
> class ab():
> def a(self):
> self.x = 99
> print self.x
> def b(self):
> print self.x
> 
> i = ab()
> i.a()
> i.b() # this works, why no lexical scoping?

Because x is an attribute.

If you don't understand what that means, read any introductory
article on OOP.

To give you a clue, if you had said:

class ab():
def a(self):
x = 99
print x
def b(self):
print x

You'd have gotten the exception you expected (assuming x wasn't
defined globally).

--RDM

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


Why no lexical scoping for a method within a class?

2008-12-17 Thread walterbyrd
For a language as well structured as Python, this seems somewhat
sloppy, and inconsistant.  Or is there some good reason for this?

Here is what I mean:

def a():
x = 99
print x

def b():
print x

a()
b() # raises an exception because x is not defined.

However in the methods are within a class, the scoping seems to work
differently.

class ab():
def a(self):
self.x = 99
print self.x
def b(self):
print self.x

i = ab()
i.a()
i.b() # this works, why no lexical scoping?
--
http://mail.python.org/mailman/listinfo/python-list


Re: Why no lexical scoping for a method within a class?

2008-12-17 Thread r
I think there is a simpler answer to all this(not to take away from
the other ones here though which are all great). When writing
procedural code how would you like it if vars inside functions were
automatically global. Your code with be blowing chunks in no time.
Thats the reason for global declarations and instance.var :)


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


Re: Why no lexical scoping for a method within a class?

2008-12-17 Thread Richard Brodie

"walterbyrd"  wrote in message 
news:518b9dd9-69c5-4d5b-bd5f-ad567be62...@b38g2000prf.googlegroups.com...

> However in the methods are within a class, the scoping seems to work
> differently.

Not really, self is a formal parameter to the function. It would be
a strange language where a function's own arguments weren't in scope.

>def b(self):
>print self.x

Try changing it to:

def b(somethingotherthanself):
print self.x



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


Re: Why no lexical scoping for a method within a class?

2008-12-17 Thread John Machin
On Dec 18, 2:19 am, walterbyrd  wrote:
> For a language as well structured as Python, this seems somewhat
> sloppy, and inconsistant.  Or is there some good reason for this?
>
> Here is what I mean:
>
> def a():
>     x = 99
>     print x
>
> def b():
>     print x
>
> a()
> b() # raises an exception because x is not defined.
>
> However in the methods are within a class, the scoping seems to work
> differently.
>
> class ab():
>     def a(self):
>         self.x = 99
>         print self.x
>     def b(self):
>         print self.x
>
> i = ab()
> i.a()
> i.b() # this works, why no lexical scoping?

Two questions for you:
(1) If you were to change the sloppy inconsistent scoping mechanism in
classes, what would you change it to?
(2) What do you think of the following:
 class ab():
 def a(self):
 self.x = 99
 print self.x
 def b(me):
 print me.x
 ?
--
http://mail.python.org/mailman/listinfo/python-list


Re: Why no lexical scoping for a method within a class?

2008-12-17 Thread walterbyrd
On Dec 17, 10:00 am, r  wrote:
> When writing
> procedural code how would you like it if vars inside functions were
> automatically global. Your code with be blowing chunks in no time.

That was my point - I consider python's ordinary use of lexical
scoping to be a good thing, and I was wondering why this "good thing"
was not used in classes, as well as outside of classes.

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


Re: Why no lexical scoping for a method within a class?

2008-12-17 Thread walterbyrd
On Dec 17, 9:04 am, rdmur...@bitdance.com wrote:

> Yes.  It's called Object Oriented Programming.

I think you mean it's *Python* Object Oriented Programming. I am not
sure that every other OO language works like that.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Why no lexical scoping for a method within a class?

2008-12-17 Thread walterbyrd
On Dec 17, 10:17 am, "Richard Brodie"  wrote:
> Not really, self is a formal parameter to the function. It would be
> a strange language where a function's own arguments weren't in scope.

Thank you, that makes sense to me.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Why no lexical scoping for a method within a class?

2008-12-17 Thread r
On Dec 17, 12:20 pm, walterbyrd  wrote:
> On Dec 17, 10:00 am, r  wrote:
>
> > When writing
> > procedural code how would you like it if vars inside functions were
> > automatically global. Your code with be blowing chunks in no time.
>
> That was my point - I consider python's ordinary use of lexical
> scoping to be a good thing, and I was wondering why this "good thing"
> was not used in classes, as well as outside of classes.

The whole point for even writing a class is for shared attributes.
Write procedural code if you don't like classes. When ever you see
self.var think of it as Class.instance(var)... makes total sense to
me? Obliviously you have not done much procedural coding or you would
know why this HAS to be. sorry if i sound rude.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Why no lexical scoping for a method within a class?

2008-12-17 Thread walterbyrd
On Dec 17, 8:41 am, prueba...@latinmail.com wrote:

> If scoping worked as you want, how, pray tell, would you define object
> attributes?- Hide quoted text -

I suppose you could do this:

class className():
varname = "whatever"
def fname(self, varname):
   . . . .

Instead of having variable defined within methods to be global
everywhere within the class.

Anyway, it's not a matter of what I like, I am just trying to
understand the reason behind the scoping rules.

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


Re: Why no lexical scoping for a method within a class?

2008-12-17 Thread pruebauno
On Dec 17, 10:19 am, walterbyrd  wrote:
> For a language as well structured as Python, this seems somewhat
> sloppy, and inconsistant.  Or is there some good reason for this?
>
> Here is what I mean:
>
> def a():
>     x = 99
>     print x
>
> def b():
>     print x
>
> a()
> b() # raises an exception because x is not defined.
>
> However in the methods are within a class, the scoping seems to work
> differently.
>
> class ab():
>     def a(self):
>         self.x = 99
>         print self.x
>     def b(self):
>         print self.x
>
> i = ab()
> i.a()
> i.b() # this works, why no lexical scoping?

If scoping worked as you want, how, pray tell, would you define object
attributes?
--
http://mail.python.org/mailman/listinfo/python-list


Re: Why no lexical scoping for a method within a class?

2008-12-17 Thread Diez B. Roggisch
walterbyrd wrote:

> For a language as well structured as Python, this seems somewhat
> sloppy, and inconsistant.  Or is there some good reason for this?
> 
> Here is what I mean:
> 
> def a():
> x = 99
> print x
> 
> def b():
> print x
> 
> a()
> b() # raises an exception because x is not defined.
> 
> However in the methods are within a class, the scoping seems to work
> differently.
> 
> class ab():
> def a(self):
> self.x = 99
> print self.x
> def b(self):
> print self.x
> 
> i = ab()
> i.a()
> i.b() # this works, why no lexical scoping?

Because what you do is to create instance variables. Why do you expect them
not working if you explicitly access them?

The real analog of your example would be this:

class ab():
   def a(self):
   x = 100
   print x

   def b(self):
   print x

which provokes the same error.

however, there *are* different scoping rules, classes don't create a lexical
scope for their own variables:


class foo(object):
x = 100

def a(self):
print x


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


Re: Why no lexical scoping for a method within a class?

2008-12-17 Thread Bruno Desthuilliers

walterbyrd a écrit :

On Dec 17, 8:41 am, prueba...@latinmail.com wrote:


If scoping worked as you want, how, pray tell, would you define object
attributes?- Hide quoted text -


I suppose you could do this:

class className():
varname = "whatever"


This defines a class attribute - that is, an attribute of the className 
class object, accessible either thru the className object or it's 
instances if not shadowed by an instance attribute by the same name/



def fname(self, varname):
   . . . .

Instead of having variable defined within methods to be global
everywhere within the class.


There's nothing like a "variable defined within (a) method", because you 
never define methods in Python - only functions. So there's no 
difference in scoping rules for functions defined within a class 
statement block or outside a class statement block.




Anyway, it's not a matter of what I like, I am just trying to
understand the reason behind the scoping rules.


Then you should start with understanding the scoping rules.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Why no lexical scoping for a method within a class?

2008-12-17 Thread Bruno Desthuilliers

walterbyrd a écrit :

On Dec 17, 9:04 am, rdmur...@bitdance.com wrote:


Yes.  It's called Object Oriented Programming.


I think you mean it's *Python* Object Oriented Programming. I am not
sure that every other OO language works like that.



Every OO languages having such a thing as a global variable makes a 
distinction between an instance attributes and a global variable. Your 
problem is that you are confusing variables and attributes. In Python, 
'anything.anyname' (note the dot) is the attribute 'anyname' of object 
'anything'.

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


Re: Why no lexical scoping for a method within a class?

2008-12-17 Thread Rhodri James
On Wed, 17 Dec 2008 15:19:32 -, walterbyrd   
wrote:



However in the methods are within a class, the scoping seems to work
differently.


Not really.  Hopefully this commentary will show you why.


class ab():
def a(self):
self.x = 99
print self.x
def b(self):
print self.x

i = ab()
This creates |i|, an instance of class |ab|.  As yet it is pure and  
virgin, having nothing but the methods that it gets from |ab|.  Soon this  
will change...



i.a()


This creates an attribute |x| in |i|, and assigns the number 99 to it.


i.b() # this works, why no lexical scoping?


This works because you ran |i.a()| first, so |i.x| exists and can be  
printed out.  Lexical scoping is going on here, you're just mistaking  
what's being scoped; it's the |self| in |b|, which is in scope because  
it's a parameter.  This particular |self| (the |i| you made earlier)  
happens to have an attribute |x|, so it all works.  If however you'd  
written:


j = ab()
j.b()

then Python would whinge mightily at you, claiming that it knoweth naught  
of this |x| attribute of which you speak, and can it go home now for this  
is a silly place.  The |self| in |b| is still in lexical scope, though.


--
Rhodri James *-* Wildebeeste Herder to the Masses
--
http://mail.python.org/mailman/listinfo/python-list


Re: Why no lexical scoping for a method within a class?

2008-12-17 Thread Chris Rebert
On Wed, Dec 17, 2008 at 4:03 PM, Rhodri James
 wrote:
> On Wed, 17 Dec 2008 15:19:32 -, walterbyrd  wrote:
>
>> However in the methods are within a class, the scoping seems to work
>> differently.
>
> Not really.  Hopefully this commentary will show you why.
>
>> class ab():
>>def a(self):
>>self.x = 99
>>print self.x
>>def b(self):
>>print self.x
>>
>> i = ab()
>
> This creates |i|, an instance of class |ab|.  As yet it is pure and virgin,
> having nothing but the methods that it gets from |ab|.  Soon this will
> change...
>
>> i.a()
>
> This creates an attribute |x| in |i|, and assigns the number 99 to it.
>
>> i.b() # this works, why no lexical scoping?
>
> This works because you ran |i.a()| first, so |i.x| exists and can be printed
> out.  Lexical scoping is going on here, you're just mistaking what's being
> scoped; it's the |self| in |b|, which is in scope because it's a parameter.
>  This particular |self| (the |i| you made earlier) happens to have an
> attribute |x|, so it all works.  If however you'd written:
>
> j = ab()
> j.b()
>
> then Python would whinge mightily at you, claiming that it knoweth naught of
> this |x| attribute of which you speak, and can it go home now for this is a
> silly place.  The |self| in |b| is still in lexical scope, though.
>

Relatedly, Python has no notion of 'declaring' instance variables in a
class (instead, you just create them in __init__ or other methods),
and class variables (in Java terminology: 'static' variables) do not
constitute a scope for variable lookup.
Python is still lexically scoped, it's just that only functions and
the "globals"/toplevel/module-level constitute scopes, not class
bodies.

Cheers,
Chris

-- 
Follow the path of the Iguana...
http://rebertia.com
--
http://mail.python.org/mailman/listinfo/python-list


Re: Why no lexical scoping for a method within a class?

2008-12-17 Thread Steven D'Aprano
On Wed, 17 Dec 2008 22:19:43 +0100, Bruno Desthuilliers wrote:

> Your
> problem is that you are confusing variables and attributes. In Python,
> 'anything.anyname' (note the dot) is the attribute 'anyname' of object
> 'anything'.

An easy mistake to make, given that scopes are just namespaces, and 
attribute access is just accessing names in namespaces too.


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


Re: Why no lexical scoping for a method within a class?

2008-12-17 Thread Steven D'Aprano
On Wed, 17 Dec 2008 10:20:21 -0800, walterbyrd wrote:

> On Dec 17, 10:00 am, r  wrote:
>> When writing
>> procedural code how would you like it if vars inside functions were
>> automatically global. Your code with be blowing chunks in no time.
> 
> That was my point - I consider python's ordinary use of lexical scoping
> to be a good thing, and I was wondering why this "good thing" was not
> used in classes, as well as outside of classes.

But it is. You're mistaking lexical scoping for object attribute access. 
The rules for lexical scoping inside a class are (almost) the same as 
they are for inside a function:

def parrot(breed):
def message(colour):
return "The %s %s has beautiful plumage." % (breed, colour)
return message("Blue")

class Parrot:
def parrot(self, breed):
def message(colour):
return "The %s %s has beautiful plumage." % (breed, colour)
return message("Blue")

And in use: 

>>> parrot("Norwegian")
'The Norwegian Blue has beautiful plumage.'
>>> p = Parrot()
>>> p.parrot("Swedish")
'The Swedish Blue has beautiful plumage.'


Notice that to have lexical scoping work, you actually have to nest the 
functions. Otherwise they are in different scopes.


This might lead you believe you can do this:

class Parrot2:
colour = "Blue"
def parrot(self, breed):
return "The %s %s has beautiful plumage." % (breed, colour)


>>> p = Parrot2()
>>> p.parrot("Norwegian")
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 4, in parrot
NameError: global name 'colour' is not defined

What's going on? Why doesn't the parrot method see the name "colour" in 
the class scope?

The reason is that the class scope is deliberately left out of the nested 
scope chain. This was a design decision from when nested scopes were 
introduced: 

"An alternative would have been to allow name binding in class
scope to behave exactly like name binding in function scope.  This
rule would allow class attributes to be referenced either via
attribute reference or simple name.  This option was ruled out
because it would have been inconsistent with all other forms of
class and instance attribute access, which always use attribute
references.  Code that used simple names would have been obscure."

http://www.python.org/dev/peps/pep-0227/

So inside the method, you need to refer to Parrot.colour (or thanks to 
the rules of attribute inheritance, self.colour).

Classes could be closures, but that could radically change the way 
methods and classes work. Depending on design decisions, it might require 
huge changes to the Python compiler. How would it change the existing 
lexical scoping in factory functions?

def factory(colour):
class Parrot:
def parrot(self, breed):
return "The %s %s has beautiful plumage." % (breed, colour)
return Parrot

>>> redparrot = factory("Red")()
>>> redparrot.parrot("Swedish")
'The Swedish Red has beautiful plumage.'


Consider a hypothetical Python with classes included in the lexical 
scoping:

class Parrot3:
colour = "Blue"
def parrot(self):
colour = "Red"


What should method parrot do? I can think of at least three possibilities:

* create a local name colour inside the method scope;
* change the class attribute Parrot3.colour to "Red";
* create an instance attribute self.colour.

Whatever solution you come up with, there is potential inconsistency with 
other parts of the language.



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