473,396 Members | 1,689 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Unclear On Class Variables

I am a bit confused. I was under the impression that:

class foo(object):
x = 0
y = 1

means that x and y are variables shared by all instances of a class.
But when I run this against two instances of foo, and set the values
of x and y, they are indeed unique to the *instance* rather than the
class.

It is late and I am probably missing the obvious. Enlightenment appreciated ...
--
----------------------------------------------------------------------------
Tim Daneliuk tu****@tundraware.com
PGP Key: http://www.tundraware.com/PGP/
Jul 18 '05 #1
12 1380
Tim Daneliuk wrote:
I am a bit confused. I was under the impression that:

class foo(object):
x = 0
y = 1

means that x and y are variables shared by all instances of a class.
But when I run this against two instances of foo, and set the values
of x and y, they are indeed unique to the *instance* rather than the
class.

It is late and I am probably missing the obvious. Enlightenment
appreciated ...


Without actual code how you set the vars, no one can answer that question.

--
Regards,

Diez B. Roggisch
Jul 18 '05 #2
On 13 Jan 2005 07:18:26 EST, Tim Daneliuk <tu****@tundraware.com> wrote:
I am a bit confused. I was under the impression that:

class foo(object):
x = 0
y = 1

means that x and y are variables shared by all instances of a class.
But when I run this against two instances of foo, and set the values
of x and y, they are indeed unique to the *instance* rather than the
class.


I can see why you might think that:
class Spam(object): .... eggs = 4
.... spam = Spam()
spam2 = Spam()
spam.eggs 4 spam2.eggs 4 spam.eggs = 2
spam.eggs 2 spam2.eggs 4

But you are being mislead by the fact that integers are immutable.
'spam.eggs = 2' is *creating* an instance member - there wasn't one
before. Have a look at what happens with a mutable object:
class Spam(object): .... eggs = [3]
.... spam = Spam()
spam2 = Spam()
spam.eggs [3] spam2.eggs [3] spam.eggs.append(5)
spam.eggs [3, 5] spam2.eggs

[3, 5]

--
Cheers,
Simon B,
si***@brunningonline.net,
http://www.brunningonline.net/simon/blog/
Jul 18 '05 #3
Hi Tim,

If you have

class Foo(object) :
x = 0
y = 1

foo = Foo()

foo.x # reads either instance or class attribute (class in this case)

foo.x = val # sets an instance attribute (because foo is instance not
class)

Foo.x = val # sets a class attribute
foo.__class.__x = val # does the same

this might be sometimes confusing. IMHO, the following is especially
nasty:
foo = Foo()
foo.x += 1

print foo.x 1 print Foo.x
0

although the += operator looks like an inplace add it isn't.
it is just syntactic sugar for foo.x = foo.x + 1.
- harold -
On 13.01.2005, at 07:18, Tim Daneliuk wrote:
I am a bit confused. I was under the impression that:

class foo(object):
x = 0
y = 1

means that x and y are variables shared by all instances of a class.
But when I run this against two instances of foo, and set the values
of x and y, they are indeed unique to the *instance* rather than the
class.

It is late and I am probably missing the obvious. Enlightenment
appreciated ...
--
-----------------------------------------------------------------------
-----
Tim Daneliuk tu****@tundraware.com
PGP Key: http://www.tundraware.com/PGP/
--
http://mail.python.org/mailman/listinfo/python-list

--
Everyone is a genius.
It's just that some people are too stupid to realize it.

Jul 18 '05 #4
Op 2005-01-13, Simon Brunning schreef <si************@gmail.com>:
On 13 Jan 2005 07:18:26 EST, Tim Daneliuk <tu****@tundraware.com> wrote:
I am a bit confused. I was under the impression that:

class foo(object):
x = 0
y = 1

means that x and y are variables shared by all instances of a class.
But when I run this against two instances of foo, and set the values
of x and y, they are indeed unique to the *instance* rather than the
class.


I can see why you might think that:
class Spam(object): ... eggs = 4
... spam = Spam()
spam2 = Spam()
spam.eggs 4 spam2.eggs 4 spam.eggs = 2
spam.eggs 2 spam2.eggs 4

But you are being mislead by the fact that integers are immutable.
'spam.eggs = 2' is *creating* an instance member - there wasn't one
before. Have a look at what happens with a mutable object:
class Spam(object): ... eggs = [3]
... spam = Spam()
spam2 = Spam()
spam.eggs [3] spam2.eggs [3] spam.eggs.append(5)
spam.eggs [3, 5] spam2.eggs

[3, 5]


Well I find this a confusing behaviour on python's part. The fact
that instance.field can mean something different, depending on
where in a statement you find it, makes the behaviour inconsistent.

I know people in general here are against declarations, but declarations
could IMO provide more consistency here and thus more obvious behaviour.

--
Antoon Pardon
Jul 18 '05 #5
Op 2005-01-13, harold fellermann schreef <ha***************@upf.edu>:
Hi Tim,

If you have

class Foo(object) :
x = 0
y = 1

foo = Foo()

foo.x # reads either instance or class attribute (class in this case)

foo.x = val # sets an instance attribute (because foo is instance not
class)

Foo.x = val # sets a class attribute
foo.__class.__x = val # does the same

this might be sometimes confusing. IMHO, the following is especially
nasty:
foo = Foo()
foo.x += 1

print foo.x 1 print Foo.x

0

although the += operator looks like an inplace add it isn't.
it is just syntactic sugar for foo.x = foo.x + 1.


Except is x belongs to a mutable class that implements the
+= operator as an inplace add.

Try the same but with x = [2]
and foo.x += [3]

--
Antoon Pardon
Jul 18 '05 #6
Simon Brunning wrote:
On 13 Jan 2005 07:18:26 EST, Tim Daneliuk <tu****@tundraware.com> wrote:
But you are being mislead by the fact that integers are immutable.
'spam.eggs = 2' is *creating* an instance member - there wasn't one
before. Have a look at what happens with a mutable object:


Simon, it's really not about mutability at all. You've changed
the example, which was binding a name (specifically setting an
attribute), to one in which you are simply calling a method on
the object. If you change your example to bind the name the
same way, even with a mutable, it will work the same way as Tim's
original did with integers:
class Spam(object): .... eggs = [3]
.... spam = Spam()
spam2 = Spam()
spam.eggs = [7]
spam2.eggs

[3]

-Peter
Jul 18 '05 #7
On Thu, 13 Jan 2005 08:56:10 -0500, Peter Hansen <pe***@engcorp.com> wrote:
Simon, it's really not about mutability at all. You've changed
the example,


Err, there *wasn't* an example, not really. The OP just mentioned
'setting the values' of instance members. That *can* mean name
binding, but (to my mind at least) it can also mean calling mutating
methods. I just wanted to show both.

--
Cheers,
Simon B,
si***@brunningonline.net,
http://www.brunningonline.net/simon/blog/
Jul 18 '05 #8
>
Well I find this a confusing behaviour on python's part. The fact
that instance.field can mean something different, depending on
where in a statement you find it, makes the behaviour inconsistent.

I know people in general here are against declarations, but declarations
could IMO provide more consistency here and thus more obvious behaviour.


Well just to show how confusing python can be, the following piece of
code.

| class Spam:
| eggs = [2, 3]
|
|
| sp1 = Spam()
| sp2 = Spam()
|
| print sp1.eggs, id(sp1.eggs)
| print sp2.eggs, id(sp2.eggs)
| print '--------------------'
|
| sp1.eggs += [4,]
|
| print sp1.eggs, id(sp1.eggs)
| print sp2.eggs, id(sp2.eggs)
| print '--------------------'
|
| Spam.eggs = [3,5]
|
| print sp1.eggs, id(sp1.eggs)
| print sp2.eggs, id(sp2.eggs)
| print '--------------------'

Which produces:

[2, 3] 1075958860
[2, 3] 1075958860
--------------------
[2, 3, 4] 1075958860
[2, 3, 4] 1075958860
--------------------
[2, 3, 4] 1075958860
[3, 5] 1075959084
--------------------

Jul 18 '05 #9
Tim Daneliuk wrote:
I am a bit confused. I was under the impression that:

class foo(object):
x = 0
y = 1

means that x and y are variables shared by all instances of a class.
What it actually does is define names with the given values *in the
class namespace*.
But when I run this against two instances of foo, and set the values
of x and y, they are indeed unique to the *instance* rather than the
class.
I imagine here you are setting instance variables, which then *mask* the
presence of class variables with the same name, because "self-relative"
name resolution looks in the instance namespace before it looks in the
class namespace.
It is late and I am probably missing the obvious. Enlightenment
appreciated ...


You can refer to class variables using the class name explicitly, both
within methods and externally:
class X: ... count = 0
... def getCt(self):
... return self.count
... def inc(self):
... self.count += 1
... x1 = X()
x2 = X()
id(x1.count) 168378284 x1.inc()
id(x1.count) 168378272 id(x2.count) 168378284 id(X.count) 168378284 x1.getCt() 1 x2.getCt() 0


regards
Steve
--
Steve Holden http://www.holdenweb.com/
Python Web Programming http://pydish.holdenweb.com/
Holden Web LLC +1 703 861 4237 +1 800 494 3119

Jul 18 '05 #10
Tim Daneliuk wrote:
I am a bit confused. I was under the impression that:

class foo(object):
x = 0
y = 1

means that x and y are variables shared by all instances of a class.
But when I run this against two instances of foo, and set the values
of x and y, they are indeed unique to the *instance* rather than the
class.


"set" as in:

obj = foo()
obj.x = 10 # set x

?

if so, the "obj.x=" line is *adding* an instance variable to the "x" object, which will
then hide the "x" at the class level.
class foo(object): .... x = 0
.... y = 1
.... obj = foo()
obj.__dict__ {} obj.x 0 obj.y 1 foo.x 0 obj.x = 10
obj.__dict__ {'x': 10} obj.x 10 foo.x 0

if you want to assign to the class variable, assign to the class variable:
obj = foo()
obj.x 0 foo.x = 20
obj.__dict__ {} obj.x 20 foo().x

20

</F>

Jul 18 '05 #11
Antoon Pardon a écrit :
Well I find this a confusing behaviour on python's part. The fact
that instance.field can mean something different, depending on
where in a statement you find it, makes the behaviour inconsistent.

I know people in general here are against declarations, but declarations
could IMO provide more consistency here and thus more obvious behaviour.

Well just to show how confusing python can be, the following piece of
code.

| class Spam:
| eggs = [2, 3]
|
|
| sp1 = Spam()
| sp2 = Spam()
|
| print sp1.eggs, id(sp1.eggs)
| print sp2.eggs, id(sp2.eggs)
| print '--------------------'
|
| sp1.eggs += [4,]
|
| print sp1.eggs, id(sp1.eggs)
| print sp2.eggs, id(sp2.eggs)
| print '--------------------'
|
| Spam.eggs = [3,5]
|
| print sp1.eggs, id(sp1.eggs)
| print sp2.eggs, id(sp2.eggs)
| print '--------------------'

Which produces:

[2, 3] 1075958860
[2, 3] 1075958860
--------------------
[2, 3, 4] 1075958860
[2, 3, 4] 1075958860
--------------------
[2, 3, 4] 1075958860
[3, 5] 1075959084
--------------------


Well ... and could someone explain this behaviour ?
I don't catch it !

Pierre
Jul 18 '05 #12
Pierre Barbier de Reuille a écrit :
Antoon Pardon a écrit :
Well I find this a confusing behaviour on python's part. The fact
that instance.field can mean something different, depending on
where in a statement you find it, makes the behaviour inconsistent.

I know people in general here are against declarations, but declarations
could IMO provide more consistency here and thus more obvious behaviour.


Well just to show how confusing python can be, the following piece of
code.

| class Spam:
| eggs = [2, 3]
| | | sp1 = Spam()
| sp2 = Spam()
| | print sp1.eggs, id(sp1.eggs)
| print sp2.eggs, id(sp2.eggs)
| print '--------------------'
| | sp1.eggs += [4,]
|
| print sp1.eggs, id(sp1.eggs)
| print sp2.eggs, id(sp2.eggs)
| print '--------------------'
|
| Spam.eggs = [3,5]
|
| print sp1.eggs, id(sp1.eggs)
| print sp2.eggs, id(sp2.eggs)
| print '--------------------'

Which produces:

[2, 3] 1075958860
[2, 3] 1075958860
--------------------
[2, 3, 4] 1075958860
[2, 3, 4] 1075958860
--------------------
[2, 3, 4] 1075958860
[3, 5] 1075959084
--------------------


Well ... and could someone explain this behaviour ?
I don't catch it !

Pierre


Ok, I think I got it ! I speak with friends working with Python too ...
It seems that "a += l" if "a" and "l" are lists is equivalent to :

a.extend(l)
a = a

The second line could seem meaningless but it is not ! Indeed, in the
example above, the first "sp1.eggs" (the one with the extend) is a class
variable but, the second "sp1.eggs" (the one before the "=") is an
instance variable !

So, at the end, we append to get sp1.eggs and Spam.eggs references to
the same structure. But sp1.eggs is an instance variable of sp1 and no
more the class variable. To test that, it's possible to modify slightly
the code with :

|sp1.eggs += [4,]
|del sp1.eggs

Then, sp1.eggs still exists !!! But it's again the class variable ...

Ok, back to the documentation ...

In the doc, there is a special case for the use of "+=" with the class
members. IMHO, this should not be !!! But, it says that :

ob.a += b

is translated into :

ob.__setattr__( "a", ob.__getattr__("a").__iadd__(b) )

My opinion is : it would be much more simpler to explain than :

a += b <=> a.__iadd__(b); a = a

and not give any special case for class members. In both cases, the
resulting behaviour is the same, but it would be less confusing.

Then, this change of scope of variables in python is very very annoying.
Both for new and old programmers (we have both in my lab ...).

Well, I hope I got it write this time ... but this is a feature to fear !!!

Pierre
Jul 18 '05 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Neil Zanella | last post by:
Hello, It seems to me that using too many variables at class scope in C++ (e.g. private data members) can be just as bad as having a C program with lots of global variables. This is especially...
8
by: dwok | last post by:
I have been wondering this for a while now. Suppose I have a class that contains some private member variables. How should I access the variables throughout the class? Should I use properties that...
4
by: Nick Dreyer | last post by:
Is it possible to see public class variables of a COM addin in Excel 97 VBA? I have successfully created the (Visual Basic 2003 .NET) COM and referenced it in an Excel 97 VBA project. The VBA...
7
by: WXS | last post by:
Vote for this idea if you like it here: http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx?feedbackid=5fee280d-085e-4fe2-af35-254fbbe96ee9...
16
by: digitalorganics | last post by:
What's the difference between initializing class variables within the class definition directly versus initializing them within the class's __init__ method? Is there a reason, perhaps in certain...
5
by: Jesper Schmidt | last post by:
When does CLR performs initialization of static variables in a class library? (1) when the class library is loaded (2) when a static variable is first referenced (3) when... It seems that...
5
by: tshad | last post by:
In VS 2003, I am setting up an abstract class that is setting up classes for each datatype of VB.Net (as well as C#). I am trying to set it up so that most of the work is done in the Abstract...
20
by: tshad | last post by:
Using VS 2003, I am trying to take a class that I created to create new variable types to handle nulls and track changes to standard variable types. This is for use with database variables. This...
3
by: Immortal Nephi | last post by:
The rule of inheritance states that you define from top to bottom. Sometimes, you want to define base class and set reference from dervied class to base class, but you violate the rule. Here is an...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.