Maxim Khitrov wrote:
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
self.list.append(self.count)
def val(self):
return (self.count, self.list)
for i in xrange(10):
c1 = Case1()
c2 = Case2()
for j in xrange(i):
c1.inc()
c2.inc()
v1, l1 = c1.val()
v2, l2 = c2.val()
print v1 == v2, l1 == l2
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. On the last line, v1 == v2 is
always True. When the type is mutable (list), you must define it in
__init__. This isn't about class attributes or shared instance
attributes/constants. This is about a small optimization in defining
per-instance variables. This optimization only applies to immutable
types.
- Max
--
http://mail.python.org/mailman/listinfo/python-list
But now you are not listening to what people are telling you. It has
*nothing* to do with the mutability/immutability of the integer and the
list your two classes create.
The difference is this:
For C1: You create 10 instances of C1. Each one creates its own
count, and a list variables, and manipulates them calls to inc and val.
Then each on is discarded as you go through the next pass on the outer loop.
For C2; You create 10 instances of C2, but these 10 instances each
manipulate values created once in the class itself. The values
manipulated by one instance of C2 in one pass through the loop are not
affected when, on the next pass through the loop, that instance is
destroyed and another instance is created.
So...
If you want a variable that records/supplies some value across *all*
instances of a class, use a class variable.
(Or use a global variable -- it would have the same effect.)
If you want a variable whose value is unique to each instance of a
class, then make it an instance variable.
Gary Herron
--
http://mail.python.org/mailman/listinfo/python-list