473,794 Members | 2,804 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Class Variable Access and Assignment

This has to do with class variables and instances variables.

Given the following:

<code>

class _class:
var = 0
#rest of the class

instance_b = _class()

_class.var=5

print instance_b.var # -> 5
print _class.var # -> 5

</code>

Initially this seems to make sense, note the difference between to last
two lines, one is refering to the class variable 'var' via the class
while the other refers to it via an instance.

However if one attempts the following:

<code>

instance_b.var = 1000 # -> _class.var = 5
_class.var = 9999 # -> _class.var = 9999

</code>

An obvious error occurs. When attempting to assign the class variable
via the instance it instead creates a new entry in that instance's
__dict__ and gives it the value. While this is allowed because of
pythons ability to dynamically add attributes to a instance however it
seems incorrect to have different behavior for different operations.

There are two possible fixes, either by prohibiting instance variables
with the same name as class variables, which would allow any reference
to an instance of the class assign/read the value of the variable. Or
to only allow class variables to be accessed via the class name itself.

Many thanks to elpargo and coke. elpargo assisted in fleshing out the
best way to present this.

perhaps this was intended, i was just wondering if anyone else had
noticed it, and if so what form would you consider to be 'proper'
either referring to class variables via the class itself or via
instances of that class. Any response would be greatly appreciated.
Graham

Nov 3 '05
166 8680
Antoon Pardon wrote:
There is no instance variable at that point. How can it add 2, to
something that doesn't exist at the moment.


Because 'a += 1' is only a shorthand for 'a = a + 1' if a is an
immutable object? Anyway, the behaviour is well documented.

http://docs.python.org/ref/augassign.html says:

An augmented assignment expression like x += 1 can be rewritten as x = x
+ 1 to achieve a similar, but not exactly equal effect. In the augmented
version, x is only evaluated once. Also, when possible, the actual
operation is performed in-place, meaning that rather than creating a new
object and assigning that to the target, the old object is modified instead.

....

For targets which are attribute references, the initial value is
retrieved with a getattr() and the result is assigned with a setattr().
Notice that the two methods do not necessarily refer to the same
variable. When getattr() refers to a class variable, setattr() still
writes to an instance variable. For example:

class A:
x = 3 # class variable
a = A()
a.x += 1 # writes a.x as 4 leaving A.x as 3
Nov 3 '05 #31
Op 2005-11-03, Stefan Arentz schreef <st***********@ gmail.com>:
Antoon Pardon <ap*****@forel. vub.ac.be> writes:

...
Fine, we have the code:

b.a += 2

We found the class variable, because there is no instance variable,
then why is the class variable not incremented by two now?
Because it really is executed as:

b.a = b.a + 2


That is an explanation, not a reason.
1. get 't'b.a and store it in a temporary 't' (found the instance)
2. add 2 to 't'
3. store 't' in 'b.a'

The last operation stores it into an instance variable.


[ I think you mean '(found the class variable)' in line 1 ]

All you are doing here is explain how the current implemantation treats
this. You are not giving arguments for why the result of this
implementation should be considered sane behaviour.
> Remember, Python is a dynamic language.


So? Python being a dynamic language doesn't prevent the following to fail:
>>> a=1
>>> def f():

... a += 2
...
>>> f()

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 2, in f
UnboundLocalErr or: local variable 'a' referenced before assignment


See the 'global' keyword.


You missed the point. If python being a dynamic language would be the
answer to the interaction between instance and class variable, why
then is the interaction between local and global variable different,
why wouldn't the f code be executed as follows

1. get a and store in in a temporary 't' (found the global)
2. add 2 to 't'
3. store 't' in 'a'

The last operation storing it in f's local namespace.

--
Antoon Pardon
Nov 3 '05 #32
Antoon Pardon <ap*****@forel. vub.ac.be> writes:
Op 2005-11-03, Stefan Arentz schreef <st***********@ gmail.com>:
Antoon Pardon <ap*****@forel. vub.ac.be> writes:

...
Fine, we have the code:

b.a += 2

We found the class variable, because there is no instance variable,
then why is the class variable not incremented by two now?


Because it really is executed as:

b.a = b.a + 2


That is an explanation, not a reason.


I'm just following the
1. get 't'b.a and store it in a temporary 't' (found the instance)
2. add 2 to 't'
3. store 't' in 'b.a'

The last operation stores it into an instance variable.


[ I think you mean '(found the class variable)' in line 1 ]

All you are doing here is explain how the current implemantation treats
this. You are not giving arguments for why the result of this
implementation should be considered sane behaviour.


Ah yes. Well, good luck with that. You seem to have decided that it is not
sane and who am I to argue with that. It depends on your state of mind :-)

The model makes sense in my opinion. If you don't like it then there are
plenty of other languages to choose from that have decided to implement
things differently.

Have fun, take care!

S.
Nov 3 '05 #33
On Thu, 03 Nov 2005 13:01:40 +0000, Antoon Pardon wrote:
Seems perfectly sane to me.

What would you expect to get if you wrote b.a = b.a + 2?
I would expect a result consistent with the fact that both times
b.a would refer to the same object.


class RedList(list):
colour = "red"

L = RedList(())

What behaviour would you expect from len(L), given that L doesn't have a
__len__ attribute?

Why do you expect
b.a += 2 to give a different result?


I didn't know I did.


It seems to me that you do.

You didn't appear to be objecting to a line like x = b.a assigning the
value of 1 to x (although perhaps you do). If that was the case, then it
is perfectly reasonable to expect b.a = x + 2 to store 3 into b.a, while
leaving b.__class__.a untouched.

Of course, if you object to inheritance, then you will object to x = b.a
as well.

Since ints are immutable objects, you shouldn't expect the value of b.a
to be modified in place, and so there is an assignment to b.a, not A.a.


You are now talking implementation details. I don't care about whatever
explanation you give in terms of implementation details. I don't think
it is sane that in a language multiple occurence of something like b.a
in the same line can refer to different objects


That's an implementation detail only in the sense that "while condition"
is a loop is an implementation detail. It is a *design* detail.

b is a name, and any reference to b (in the same namespace) will refer
to the same object. At least until you rebind it to another object.

But b.a is not a name, it is an attribute lookup, and by Python's rules of
inheritance that lookup will look up attributes in the instance, the
class, and finally any superclasses.

If you persist in thinking of b.a as a name referring to a single object,
of course you will be confused by the behaviour. But that's not what
attribute lookup does.

On the right hand side of an assignment, it will return the first existing
of b.__dict__['a'] or b.__class__.__d ict__['a']. On the left hand of an
assignment, it will store into b.__dict__['a'].

I think it even less sane, if the same occurce of b.a refers to two
different objects, like in b.a += 2


Then it seems to me you have some serious design problems. Which would you
prefer to happen?
# Scenario 1
# imaginary pseudo-Python code with no inheritance:
class Paragraph:
ls = '\n' # line separator

para = Paragraph()
para.ls

=> AttributeError - instance has no attribute 'ls'

# Scenario 2
# imaginary pseudo-Python code with special inheritance:
class Paragraph:
ls = '\n' # line separator

linux_para = Paragraph()
windows_para = Paragraph()
windows_para.ls = '\n\r' # magically assigns to the class attribute
linux_para.ls

=> prints '\n\r'
# Scenario 3
# Python code with standard inheritance:
class Paragraph:
ls = '\n' # line separator

linux_para = Paragraph()
windows_para = Paragraph()
windows_para.ls = '\n\r'
linux_para.ls

=> prints '\n'

--
Steven.

Nov 3 '05 #34
On Thu, 03 Nov 2005 14:27:48 +0100, Sybren Stuvel wrote:
Antoon Pardon enlightened us with:
I would expect a result consistent with the fact that both times b.a
would refer to the same object.


"b.a" is just a name, not a pointer to a spot in memory. Getting the
value associated with that name is something different from assigning
a new value to that name.


You've got the right concept, but not the right terminology. The "b"
before the dot is a name. The "a" after the dot is a name. But the whole
thing together is not a name: b.a is an attribute reference. You wouldn't
call b["a"] a name, and you shouldn't call b.a a name either.
--
Steven.

Nov 3 '05 #35
On Thu, 03 Nov 2005 13:35:35 +0000, Antoon Pardon wrote:
Suppose I have code like this:

for i in xrange(1,11):
b.a = b.a + i

Now the b.a on the right hand side refers to A.a the first time through
the loop but not the next times. I don't think it is sane that which
object is refered to depends on how many times you already went through
the loop.


Well, then you must think this code is *completely* insane too:

py> x = 0
py> for i in range(1, 5):
.... x += i
.... print id(x)
....
140838200
140840184
140843160
140847128

Look at that: the object which is referred to depends on how many times
you've already been through the loop. How nuts is that?

I guess that brings us back to making ints mutable. I can't wait until I
can write 1 - 0 = 99 and still be correct!
--
Steven.

Nov 3 '05 #36
On Thu, 03 Nov 2005 14:13:13 +0000, Antoon Pardon wrote:
Fine, we have the code:

b.a += 2

We found the class variable, because there is no instance variable,
then why is the class variable not incremented by two now?


Because b.a += 2 expands to b.a = b.a + 2. Why would you want b.a =
<something> to correspond to b.__class__.a = <something>?

I'm not saying that it couldn't, if that was the model for inheritance you
decided to use. I'm asking why would you want it? What is your usage case
that demonstrates that your preferred inheritance model is useful?
--
Steven.

Nov 3 '05 #37
On Thu, 03 Nov 2005 15:13:52 +0100, Eric Nieuwland wrote:
Stefan Arentz wrote:
It is really simple. When you say b.a then the instance variable 'a'
is looked up first. If it does not exist then a class variable lookup
is done.
This mixing of class and instance variable might be the cause of
confusion...

I think of it as follows:
1 When the class statement ends a class object is created which is
filled by all the statements inside the class statement
This means all variables and functions (methods) are created according
to the description.
NOTE This happens just once.


Yes.
2 When an instance of the class is created, what effectively happens is
that a shallow copy of the class object is made.
Simple values and object references are copied.
No.

py> class Parrot:
.... var = 0
....
py> p = Parrot()
py> Parrot.var is p.var
True
py> Parrot.var = {"Hello world": [0, 1, 2]}
py> Parrot.var is p.var
True

It all boils down to inheritance. When Python does a look up of an
attribute, it looks for an instance attribute first (effectively trying
instance.__dict __['name']). If that fails, it looks up the class second
with instance.__clas s__.__dict__['name'], and if that fails it goes into a
more complex search path looking up any superclasses (if any).

This explains:
- why methods and complex objects (e.g. lists) are shared among
instances of a class and the class itself
- simple values are not shared


No. it is all about the inheritance, and mutable/immutable objects.

--
Steven.

Nov 3 '05 #38
Steven D'Aprano wrote:
On Thu, 03 Nov 2005 15:13:52 +0100, Eric Nieuwland wrote:
2 When an instance of the class is created, what effectively happens
is
that a shallow copy of the class object is made.
Simple values and object references are copied.


No.

py> class Parrot:
... var = 0
...
py> p = Parrot()
py> Parrot.var is p.var
True
py> Parrot.var = {"Hello world": [0, 1, 2]}
py> Parrot.var is p.var
True

It all boils down to inheritance. When Python does a look up of an
attribute, it looks for an instance attribute first (effectively trying
instance.__dict __['name']). If that fails, it looks up the class second
with instance.__clas s__.__dict__['name'], and if that fails it goes
into a
more complex search path looking up any superclasses (if any).


Note my use of "effectivel y" and "shallow copy". Your example
demonstrates how Python postpones the shallow copy until you tell the
object to differ from the class/

The examples used only use a class an an instance thereof. They are
valid without inheritance.
This explains:
- why methods and complex objects (e.g. lists) are shared among
instances of a class and the class itself
- simple values are not shared


No. it is all about the inheritance, and mutable/immutable objects.


NO. You're referring to the implemented mechanism. Other
implementations with the same semantics are possible.

Nov 3 '05 #39
In article <dk**********@w ake.carmen.se>,
Magnus Lycka <ly***@carmen.s e> wrote:
....
On the other hand:
>>> class C: ... a = [1]
... >>> b=C()
>>> b.a += [2]
>>> b.a [1, 2] >>> C.a

[1, 2]

I can understand that Guido was a bit reluctant to introduce
+= etc into Python, and it's important to understand that they
typically behave differently for immutable and mutable objects.


As far as I know, Guido has never added a feature reluctantly.
He can take full responsibility for this misguided wart.

Donn Cave, do**@u.washingt on.edu
Nov 3 '05 #40

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

Similar topics

106
5615
by: A | last post by:
Hi, I have always been taught to use an inialization list for initialising data members of a class. I realize that initialsizing primitives and pointers use an inialization list is exactly the same as an assignment, but for class types it has a different effect - it calls the copy constructor. My question is when to not use an initalisation list for initialising data members of a class?
5
2149
by: xuatla | last post by:
Hi, I encountered the following compile error of c++ and hope to get your help. test2.cpp: In member function `CTest CTest::operator+=(CTest&)': test2.cpp:79: error: no match for 'operator=' in '*this = CTest::operator+(CTest&)((+t2))' test2.cpp:49: error: candidates are: CTest CTest::operator=(CTest&) make: *** Error 1
5
8732
by: Chris | last post by:
Hi, I don't get the difference between a struct and a class ! ok, I know that a struct is a value type, the other a reference type, I understand the technical differences between both, but conceptually speaking : when do I define something as 'struct' and when as 'class' ? for example : if I want to represent a 'Time' thing, containing : - data members : hours, mins, secs
9
1931
by: NevilleDNZ | last post by:
Can anyone explain why "begin B: 123" prints, but 456 doesn't? $ /usr/bin/python2.3 x1x2.py begin A: Pre B: 123 456 begin B: 123 Traceback (most recent call last): File "x1x2.py", line 13, in ? A() File "x1x2.py", line 11, in A
14
2645
by: lovecreatesbea... | last post by:
Could you tell me how many class members the C++ language synthesizes for a class type? Which members in a class aren't derived from parent classes? I have read the book The C++ Programming Language, but there isn't a detail and complete description on all the class members, aren't they important to class composing? Could you explain the special class behavior in detail? Thank you very much.
20
4045
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 tells me if a variable has changed, give me the original and current value, and whether the current value and original value is/was null or not. This one works fine but is recreating the same methods over and over for each variable type. ...
20
1484
by: d.s. | last post by:
I've got an app with two classes, and one class (InventoryInfoClass) is an object within the other class (InventoryItem). I'm running into problems with trying to access (get/set) a private variable within the included class (InventoryInfo) from the "including" class (InventoryItem). Here's the code, trimmed down. I've included ********* at the start of the first line that's blowing up on me. I'm sure others that try to access the...
16
3450
by: John Doe | last post by:
Hi, I wrote a small class to enumerate available networks on a smartphone : class CNetwork { public: CNetwork() {}; CNetwork(CString& netName, GUID netguid): _netname(netName), _netguid(netguid) {}
0
9672
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9519
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10213
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
10000
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9037
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7538
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6779
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5563
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
2920
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.