Maxim Khitrov a écrit :
On Sat, Mar 14, 2009 at 2:07 PM, Gary Herron <gher...@islandtraining.com> wrote:
Maxim Khitrov wrote:
Very simple question on the preferred coding style. I frequently write
classes that have some data members initialized to immutable values.
For example:

class Test(object):
   def __init__(self):
       self.some_value = 0
       self.another_value = None

Similar effect can be achieved by defining some_value and
another_value for the entire class, like so:

class Test(object):
   some_value = 0
   another_value = None

The advantage of doing this is that the assignments are evaluated once
and thus the creation of that class is a bit faster. Access is still
performed through self.some_value and self.another_value. Is there a
reason to prefer the first style over the second?

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

Such things are often called class attributes, and the are fine.  If you
look through Python's standard library,  you will find many examples of
class attributes.

However, you appear to have either a misuse or misconception of the word
"immutable' here.   Whether the value you assign to a class attribute is
mutable or immutable is irrelevant.   Also whether you plan on leaving the
value constant or not is also not relevant.
What does matter is this:  If every instance wants access to a single value
(immutable or not), use a class attribute, otherwise use an instance
attribute.

Gary Herron

Perhaps a different example would help explain what I'm trying to do:

class Case1(object):
        def __init__(self):
                self.count = 0
                self.list  = []

        def inc(self):
                self.count += 1
                self.list.append(self.count)

        def val(self):
                return (self.count, self.list)

class Case2(object):
        count = 0
        list  = []

        def inc(self):
                self.count += 1

This above statement does 3 things:

1/ read "self.count", which, *the first time this method is called*, resolves to self.__class__.count since by that time, there's no instance attribute named 'count'

2/ add one to the int object returned by looking up 'self.count'

3/ store the result as instance attribute named 'count'.

IOW, the first calls to the method reads the class 'count' attribute and creates the instance 'count' attribute. Subsequent calls will resolve 'self.count' as the instance attribute since it now exists.


                self.list.append(self.count)

And this statement:

1/ read 'self.list', which resolves to self.__class__.list (the class attribute) since there's no instance attribute named 'list'

2/ mutate the class attribute


The only difference between Case1 and Case2 classes is where the count
and list attributes are defined. You will notice that for an immutable
type (count), this doesn't matter.

cf above.

On the last line, v1 == v2 is
always True. When the type is mutable (list), you must define it in
__init__.

Try rebinding self.list instead of mutating it, and you'll find out that it's not related to immutable/mutable types, but to how Python's object model works wrt/ attribute lookup and attribute binding.

An simple example being worth a thousand words:

class Case3(object):
    count = 0
    list  = []

    def inc(self):
        print self.__dict__
        self.count += 1
        self.list = self.list + [self.count]
        print self.__dict__

    def val(self):
        return (self.count, self.list)

>>> c = Case3()
>>> print c.__dict__
{}
>>> print c.__class__.__dict__
{'count': 0, '__module__': '__main__', 'val': <function val at 0xb7c7bd4c>, 'list': [], '__dict__': <attribute '__dict__' of 'Case3' objects>, '__weakref__': <attribute '__weakref__' of 'Case3' objects>, '__doc__': None, 'inc': <function inc at 0xb7c81844>}
>>> c.inc()
{}
{'count': 1, 'list': [1]}
>>> print c.__dict__
{'count': 1, 'list': [1]}
>>> print c.__class__.__dict__
{'count': 0, '__module__': '__main__', 'val': <function val at 0xb7c7bd4c>, 'list': [], '__dict__': <attribute '__dict__' of 'Case3' objects>, '__weakref__': <attribute '__weakref__' of 'Case3' objects>, '__doc__': None, 'inc': <function inc at 0xb7c81844>}
>>>


This isn't about class attributes or shared instance
attributes/constants.

Yes, it is.

This is about a small optimization in defining
per-instance variables. This optimization only applies to immutable
types.

Wrong conclusions, sorry.

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

Reply via email to