Re: Scope and classes

2009-08-19 Thread Bruno Desthuilliers

Chris Rebert a écrit :
(snip)

To access class-level variables from within instance methods of the
class, you have 2 options:
A. Use the class name, i.e. Abc.message
B. Reference the class indirectly, i.e. self.__class__.message


Or even simpler - *if* there's no synonym instance attribute:

= self.message

Attribute lookup will try to resolve the attribute name on the class 
(and it's parent classes) if it's not found on the instance.


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


Re: Scope and classes

2009-08-19 Thread Bruno Desthuilliers

David a écrit :
(snip)


Out of 'Abc.message' and 'self.message', which is the favoured
convention? It would be very easy to accidentally override
'self.messages' with an instance attribute!


Only use 'Abc.message' if you want to make sure you get the Abc class 
'message' attribute - that is, if you want to skip possible overrides in 
subclasses. As far as I'm concerned, I'd tend to consider this bad style 
 unless it's a very very specific implementation point of an abstract 
class (in which case it would probably be named '__message' to prevent 
accidental override) - but YMMV of course.


Use 'self.__class__.message' (or 'type(self).message') if you want to 
make sure you get the class 'message' attribute - that is, if you want 
to honor possible overrides in subclasses, but not per-instance 
override. But then - at least in your example code - I'd use a classmethod:


class Abc:
message = 'Hello World'

@classmethod
def print_message(cls):
print cls.message


Now the most common idiom - that is, outside classmethods - is to just 
use 'self.message'. Someone (even you) might have a very valid reason to 
 override the 'message' attribute on a per-instance basis. FWIW, if you 
start to worry about possible accidental overrides here, then Python 
might not be the right language for you - nothing prevents accidental 
overrides of method and even the class (the '__class__' attribute) 
itself - yes, they are all attributes, and you can dynamically override 
them !-)

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


Scope and classes

2009-08-18 Thread David
Hi all,

I'm trying to understand how scopes work within a class definition.
I'll quickly illustrate with an example. Say I had the following class
definition:

class Abc:
message = 'Hello World'

def print_message(self):
print message

 instance = Abc()
 instance.print_message()
NameError: global name 'message' not defined

My question is, why? message is not defined in print_message, but it
is defined in the enclosing scope (the class)?

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


Re: Scope and classes

2009-08-18 Thread Chris Rebert
On Tue, Aug 18, 2009 at 3:47 PM, Daviddavidsh...@googlemail.com wrote:
 Hi all,

 I'm trying to understand how scopes work within a class definition.
 I'll quickly illustrate with an example. Say I had the following class
 definition:

 class Abc:
    message = 'Hello World'

    def print_message(self):
        print message

 instance = Abc()
 instance.print_message()
 NameError: global name 'message' not defined

 My question is, why? message is not defined in print_message, but it
 is defined in the enclosing scope (the class)?

A class' scope is never consulted when resolving variable names in its methods.

The scopes consulted are roughly (and in this order):
1. Local variable scope (i.e. of the current function/method)
2. Enclosing functions (if you have functions nested inside other functions)
3. Globals (i.e. module-level variables)
3. Builtins (i.e. the built-in functions and methods, such as len())

To access class-level variables from within instance methods of the
class, you have 2 options:
A. Use the class name, i.e. Abc.message
B. Reference the class indirectly, i.e. self.__class__.message

Cheers,
Chris
--
http://blog.rebertia.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Scope and classes

2009-08-18 Thread David
On Aug 19, 12:16 am, Chris Rebert c...@rebertia.com wrote:
 On Tue, Aug 18, 2009 at 3:47 PM, Daviddavidsh...@googlemail.com wrote:
  Hi all,

  I'm trying to understand how scopes work within a class definition.
  I'll quickly illustrate with an example. Say I had the following class
  definition:

  class Abc:
     message = 'Hello World'

     def print_message(self):
         print message

  instance = Abc()
  instance.print_message()
  NameError: global name 'message' not defined

  My question is, why? message is not defined in print_message, but it
  is defined in the enclosing scope (the class)?

 A class' scope is never consulted when resolving variable names in its 
 methods.

 The scopes consulted are roughly (and in this order):
 1. Local variable scope (i.e. of the current function/method)
 2. Enclosing functions (if you have functions nested inside other functions)
 3. Globals (i.e. module-level variables)
 3. Builtins (i.e. the built-in functions and methods, such as len())

 To access class-level variables from within instance methods of the
 class, you have 2 options:
 A. Use the class name, i.e. Abc.message
 B. Reference the class indirectly, i.e. self.__class__.message

 Cheers,
 Chris
 --http://blog.rebertia.com

Ah, thanks!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Scope and classes

2009-08-18 Thread Steven D'Aprano
On Tue, 18 Aug 2009 15:47:09 -0700, David wrote:

 Hi all,
 
 I'm trying to understand how scopes work within a class definition. I'll
 quickly illustrate with an example. Say I had the following class
 definition:
 
 class Abc:
 message = 'Hello World'
 
 def print_message(self):
 print message
 
 instance = Abc()
 instance.print_message()
 NameError: global name 'message' not defined
 
 My question is, why? message is not defined in print_message, but it is
 defined in the enclosing scope (the class)?

It's a deliberate design decision. I don't recall the reasons for it, but 
the class namespace is deliberately excluded from the method scope.

The correct way of writing the above is:

class Abc:
message = 'Hello World'
def print_message(self):
print self.message


self.message will first search the instance namespace for an attribute 
`message`, then search the class, then any superclasses. If you 
specifically want the class attribute, even if the instance masks it with 
an instance attribute of the same name, you do this instead:

print self.__class__.message



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


Re: Scope and classes

2009-08-18 Thread Jan Kaliszewski

19-08-2009 o 00:47:09 David davidsh...@googlemail.com wrote:


Hi all,

I'm trying to understand how scopes work within a class definition.
I'll quickly illustrate with an example. Say I had the following class
definition:

class Abc:
message = 'Hello World'

def print_message(self):
print message


instance = Abc()
instance.print_message()

NameError: global name 'message' not defined

My question is, why? message is not defined in print_message, but it
is defined in the enclosing scope (the class)?


Note that when *running* the code that is *inside* print_message() method
called within the global scope, the outer (enclosing) scope is indeed the
global scope (the scope in which e.g. 'instance' name exists; note that
e.g. 'print instance' in that method would be ok).

As Chris wrote, class' scope (contrary to outer function scope) is not
considered as the 'enclosing' scope.

The only ways to reach Abc's attribute 'message' from that method are:
* 'Abc.message'
* 'self.__class__.message'
* 'self.message' (unless there is an instance attribute 'message' which
overrides the class attribute).

Cheers,
*j

--
Jan Kaliszewski (zuo) z...@chopin.edu.pl
--
http://mail.python.org/mailman/listinfo/python-list


Re: Scope and classes

2009-08-18 Thread Jan Kaliszewski

19-08-2009 o 02:10:58 Jan Kaliszewski z...@chopin.edu.pl wrote:


The only ways to reach Abc's attribute 'message' from that method are:
* 'Abc.message'
* 'self.__class__.message'
* 'self.message' (unless there is an instance attribute 'message' which
overrides the class attribute).


And of course getattr(Abc), getattr(self.__class__) etc. :-)

--
Jan Kaliszewski (zuo) z...@chopin.edu.pl
--
http://mail.python.org/mailman/listinfo/python-list


Re: Scope and classes

2009-08-18 Thread David
On Aug 19, 1:17 am, Jan Kaliszewski z...@chopin.edu.pl wrote:
 19-08-2009 o 02:10:58 Jan Kaliszewski z...@chopin.edu.pl wrote:

  The only ways to reach Abc's attribute 'message' from that method are:
  * 'Abc.message'
  * 'self.__class__.message'
  * 'self.message' (unless there is an instance attribute 'message' which
  overrides the class attribute).

 And of course getattr(Abc), getattr(self.__class__) etc. :-)

 --
 Jan Kaliszewski (zuo) z...@chopin.edu.pl

Out of 'Abc.message' and 'self.message', which is the favoured
convention? It would be very easy to accidentally override
'self.messages' with an instance attribute!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Scope and classes

2009-08-18 Thread Ben Finney
Ben Finney ben+pyt...@benfinney.id.au writes:

 Right. So you use ‘Abc.message’ when you specifically want a class
 independent of any instance

That's “a class attribute independent of any instance”, of course.

-- 
 \“Humanity has advanced, when it has advanced, not because it |
  `\ has been sober, responsible, and cautious, but because it has |
_o__)been playful, rebellious, and immature.” —Tom Robbins |
Ben Finney
-- 
http://mail.python.org/mailman/listinfo/python-list