Class variables static by default?

K

KarlRixon

Given the following script, I'd expect p1.items to just contain
["foo"] and p2.items to contain ["bar"] but they both contain ["foo",
"bar"].

Why is this? Are object variables not specific to their instance?

---------------------------
#!/usr/bin/env python

class Parser:
items = []
def add_item(self, item):
self.items.append(item)

p1 = Parser()
p1.add_item("foo")
p2 = Parser()
p2.add_item("bar")

print p1
print p2
print p1.items
print p2.items
----------------------------

Output:
<__main__.Parser instance at 0x7fd812ccc098>
<__main__.Parser instance at 0x7fd812ccc0e0>
['foo', 'bar']
['foo', 'bar']
 
J

John Posner

Given the following script, I'd expect p1.items to just contain
["foo"] and p2.items to contain ["bar"] but they both contain ["foo",
"bar"].

Why is this? Are object variables not specific to their instance?

---------------------------
#!/usr/bin/env python

class Parser:
items = []
def add_item(self, item):
self.items.append(item)

<snip>

You're using a *class attribute* instead of an *instance attribute*.
Change the class definition to:

class Parser:
def __init__(self):
self.items = []

def add_item(self, item):
self.items.append(item)

-John
 
C

Cameron Simpson

| Given the following script, I'd expect p1.items to just contain
| ["foo"] and p2.items to contain ["bar"] but they both contain ["foo",
| "bar"].
|
| Why is this? Are object variables not specific to their instance?

You haven't instatiated "items" in the object instance, so python finds
it further out in the class. One class, one variable; it looks "static".

Compare this (yours):

class Parser:
items = []
def add_item(self, item):
self.items.append(item)

with this:

class Parser:
def __init__(self):
self.items = []
def add_item(self, item):
self.items.append(item)

The first makes an "items" in the class namespace.

The second makes an "items" in each object as it is initialised.

Run the rest of your code as is and compare.

When you say "self.items" python looks first in the object and then in
the class. Your code didn't put it in the object namespace, so it found
the one in the class.

Cheers,
--
Cameron Simpson <[email protected]> DoD#743
http://www.cskk.ezoshosting.com/cs/

I have always been a welly man myself. They are superb in wet grass, let
alone lagoons of pig shit. - Julian Macassey
 
L

Lie Ryan

Given the following script, I'd expect p1.items to just contain
["foo"] and p2.items to contain ["bar"] but they both contain ["foo",
"bar"].

Why is this? Are object variables not specific to their instance?

First of all, dump all the preconception of what 'static' and 'class
variable' means in any previous language you've learned. Those terms is
not the same in python, and not even referring to a similar concept.

In python, 'class variable' is a variable that belongs to a class; not
to the instance and is shared by all instance that belong to the class.

In contrast, 'instance variable' belongs to the instance, and each
instance can make their instance variables refers to different objects
than the other instances.

Note that, in python, an object can be "owned" by multiple variables, or
more precisely "an object can have multiple names".

'static' in python refers to 'staticmethod', these are called
'classmethod' in other languages (C/C++/Java). Python's 'classmethod' is
an entirely different beast than 'classmethod' in other languages.

'staticmethod' in python is a method in a class that is not bound to the
class nor the instance; the class is merely used as organizational tool.
'classmethod' in python is a method that is bound to the class instead
of the instance; the first argument (self/cls) of a 'classmethod' is
bound to the class instead of the instance.
 
S

Steven D'Aprano

In python, 'class variable' is a variable that belongs to a class; not
to the instance and is shared by all instance that belong to the class.

Surely, since string variables are strings, and float variables are
floats, and bool variables are bools, and module variables are modules, a
class variable will be a class and an instance variable will be an
instance?
In contrast, 'instance variable' belongs to the instance, and each
instance can make their instance variables refers to different objects
than the other instances.

The usual term used in Python is "class attribute" and "instance
attribute" for the named fields of a class or instance.
 
C

Chris Rebert

Surely, since string variables are strings, and float variables are
floats, and bool variables are bools, and module variables are modules, a
class variable will be a class and an instance variable will be an
instance?

As they say, the exception proves the rule. :)

Cheers,
Chris
 
G

Gabriel Genellina

En Sun, 20 Dec 2009 01:16:16 -0300, Steven D'Aprano
Surely, since string variables are strings, and float variables are
floats, and bool variables are bools, and module variables are modules, a
class variable will be a class and an instance variable will be an
instance?


The usual term used in Python is "class attribute" and "instance
attribute" for the named fields of a class or instance.

I agree with your interpretation of "class variable", but you'll have to
rewrite parts of the official Python documentation so it becomes
consistent with it. The phrase "class variable" appears about 30 times,
always meaning "class attribute"; four of them in the Language Reference,
section "Class definitions", where the OP's issue is discussed:

"Programmer’s note: Variables defined in the class definition are class
variables; they are shared by all instances. To create instance variables,
they can be set in a method with self.name = value. Both class and
instance variables are accessible through the notation “self.name“, and an
instance variable hides a class variable with the same name when accessed
in this way. Class variables can be used as defaults for instance
variables, but using mutable values there can lead to unexpected results.
For new-style classes, descriptors can be used to create instance
variables with different implementation details."

http://docs.python.org/reference/compound_stmts.html#class-definitions
 
D

Daniel Fetchinson

In python, 'class variable' is a variable that belongs to a class; not
I agree with your interpretation of "class variable", but you'll have to
rewrite parts of the official Python documentation so it becomes
consistent with it. The phrase "class variable" appears about 30 times,
always meaning "class attribute"; four of them in the Language Reference,
section "Class definitions", where the OP's issue is discussed:

"Programmer’s note: Variables defined in the class definition are class
variables; they are shared by all instances. To create instance variables,
they can be set in a method with self.name = value. Both class and
instance variables are accessible through the notation “self.name“, and an
instance variable hides a class variable with the same name when accessed
in this way. Class variables can be used as defaults for instance
variables, but using mutable values there can lead to unexpected results.
For new-style classes, descriptors can be used to create instance
variables with different implementation details."

I don't think Steven cares much, he loves this type of nitpicking and
uber pedantic formulations, but only if he can apply it to other
people's post :)

I found that his posts are generally useful and helpful, one just has
to cut all the nitpicking, an example of which is the one you
responded to, and then everything is fine.

Duck and run.....
Daniel
 
S

Steven D'Aprano

I don't think Steven cares much, he loves this type of nitpicking and
uber pedantic formulations, but only if he can apply it to other
people's post :)

Heh heh :)

I actually do care, because (not having a Java/C++ background) I actually
do get a mental "double-take" every time I read about "class variables".
It takes a real effort of will to remind myself that they're probably not
talking about something like this:

for theclass in (int, float, Decimal, Fraction):
do_something_with(theclass)



I found that his posts are generally useful and helpful, one just has to
cut all the nitpicking, ...

Technically you don't have to cut *all* the nitpicking, cutting 87.3% of
it is sufficient.
 
D

Daniel Fetchinson

I don't think Steven cares much, he loves this type of nitpicking and
Heh heh :)

I actually do care, because (not having a Java/C++ background) I actually
do get a mental "double-take" every time I read about "class variables".
It takes a real effort of will to remind myself that they're probably not
talking about something like this:

for theclass in (int, float, Decimal, Fraction):
do_something_with(theclass)

Right. I figured you don't have much of a background in other OO
languages but actually some background helps with python too. For one
it helps communicating with other people on this list who do come from
Java/C++/etc and also because python is heavily influenced by
Java/C++/etc.

Also, programming is not about a specific language but about
programming :) The concepts are general, maybe it's spelled
differently in python and java and C++ etc etc but the programmers in
all these languages do talk about the same stuff.
Technically you don't have to cut *all* the nitpicking, cutting 87.3% of
it is sufficient.

Touche! :)

Cheers,
Daniel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,154
Members
46,702
Latest member
LukasConde

Latest Threads

Top