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/ 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
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/
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.
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
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
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
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/
> 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
--------------------
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
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>
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
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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
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...
|
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...
|
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,...
|
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...
|
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...
|
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,...
| |