473,769 Members | 6,597 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 8669
On Fri, 04 Nov 2005 07:31:46 +0000, Antoon Pardon wrote:
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.


And again this argument. Like it or leave it, as if one can't in general
like the language, without being blind for a number of shortcomings.

It is this kind of recations that make me think a number of people is
blindly devoted to the language to the point that any criticism of
the language becomes intollerable.


There are good usage cases for the current inheritance behaviour. I asked
before what usage case or cases you have for your desired behaviour, and
you haven't answered. Perhaps you missed the question? Perhaps you haven't
had a chance to reply yet? Or perhaps you have no usage case for the
behaviour you want.

Some things are a matter of taste: should CPython prefer <> or != for not
equal? Some things are a matter of objective fact: should CPython use a
byte-code compiler and virtual machine, or a 1970s style interpreter that
interprets the source code directly?

The behaviour you are calling "insane" is partly a matter of taste, but it
is mostly a matter of objective fact. I believe that the standard
model for inheritance that you call insane is rational because it is
useful in far more potential and actual pieces of code than the behaviour
you prefer -- and the designers of (almost?) all OO languages seem to
agree with me.

The standard behaviour makes it easy for code to do the right thing in
more cases, without the developer taking any special steps, and in the
few cases where it doesn't do the right thing (e.g. when the behaviour you
want is for all instances to share state) it is easy to work around. By
contrast, the behaviour you want seems to be of very limited usefulness,
and it makes it difficult to do the expected thing in almost all cases,
and work-arounds are complex and easy to get wrong.

The standard behaviour makes it easy for objects to inherit state, and
easy for them to over-ride defaults. The behaviour(s) you and Graham want
have awkward side-effects: your proposed behaviour would mean that class
attributes would mask instance attributes, or vice versa, meaning that
the programmer would have to jump through hoops to get common types of
behaviour like inheriting state.

The behaviour you want would make it too easy to inadvertently have
instances share state. Normally we want instances to share behaviour but
have unique states -- you would change that. Why? If it is just a matter
of taste, you are welcome to your opinion. But you don't say that the
standard behaviour is "ugly", you say it is "insane", that is, irrational,
and that the behaviour you want is rational.

That's an objective claim: please explain what makes your behaviour more
rational than the standard behaviour. Is your behaviour more useful? Does
it make code easier to write? Does it result in more compact code? What
usage cases?

Or is it just a subjective judgement on your part that it would be neater?
--
Steven.

Nov 4 '05 #81
Paul Rubin wrote:
Stefan Arentz <st***********@ gmail.com> writes:
Are you seriously saying there's lots of Python projects that would
break if this particular weirdness were fixed?
I have no numbers of course. But, why is this a weirdness?

Do you seriously think the number is larger than zero? Do you think
that's any good way to write code?

Well it would break the Medusa asyncore/asynchat-based server software,
so I can confidently predict the number would be greater than zero, yes.

Several fine programmers have relied on the (documented) behavior, I
suspect, as it's a convenient way to install per-instance defaults, for
example.
Examples of the weirdness have already been given. My favorite is the
one where b.a is a list instead of an integer, in which case the class
variable gets updated instead of an instance variable getting created.
If you don't find the inconsistency to be weird, then ducky for you.


Ho, hum.
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.python.org/pycon/

Nov 4 '05 #82
Antoon Pardon wrote:
Op 2005-11-04, Steve Holden schreef <st***@holdenwe b.com>: [...]
I suppose ultimately I'm just more pragmatic than you.

It has nothing to do with being more pragmatic. Being pragmatic
is about how you handle things with real life projects. It has
little to do with the degree in which you agree with the design
of the tool you have to work with. I would say I am more pragmatic
than most defenders of python, because when it comes done to
do my work, I just use python as best as I can, while a lot
of people here seem to think that every little criticism I have
is enough to go and look for a different language.

No, being pragmatic is to do with accepting what is rather than wasting
time wishing it were otherwise, particularly when the "insane" behavior
was actually a deliberate design choice. Which is why it doesn't work
the same as non-local references in nested scopes.
Plus I started
using Icon, whose assignment semantics are very similar, back in the
1970's, so Python's way of doing things fits my brain quite nicely,
thank you.

So, people can probably say that about any language they started with.
That a language suits a certain persons brain, may say more about
the person than about the language.

I wasn't trying to make a point about the language. I was merely (and I
thought charitably) trying to explain why I appear to be blind to the
"insanity" you see all around you.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.python.org/pycon/

Nov 4 '05 #83
Op 2005-11-04, Steven D'Aprano schreef <st***@REMOVETH IScyber.com.au> :
On Fri, 04 Nov 2005 07:31:46 +0000, Antoon Pardon wrote:
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.
And again this argument. Like it or leave it, as if one can't in general
like the language, without being blind for a number of shortcomings.

It is this kind of recations that make me think a number of people is
blindly devoted to the language to the point that any criticism of
the language becomes intollerable.


There are good usage cases for the current inheritance behaviour. I asked
before what usage case or cases you have for your desired behaviour, and
you haven't answered. Perhaps you missed the question? Perhaps you haven't
had a chance to reply yet? Or perhaps you have no usage case for the
behaviour you want.


There are good use cases for a lot of things python doesn't provide.
There are good use cases for writable closures, but python doesn't
provide it, shrug, I can live with that. Use cases is a red herring
here.
Some things are a matter of taste: should CPython prefer <> or != for not
equal? Some things are a matter of objective fact: should CPython use a
byte-code compiler and virtual machine, or a 1970s style interpreter that
interprets the source code directly?

The behaviour you are calling "insane" is partly a matter of taste, but it
is mostly a matter of objective fact. I believe that the standard
model for inheritance that you call insane is rational because it is
useful in far more potential and actual pieces of code than the behaviour
you prefer -- and the designers of (almost?) all OO languages seem to
agree with me.
I didn't call the model for inheritance insane.
The standard behaviour makes it easy for code to do the right thing in
more cases, without the developer taking any special steps, and in the
few cases where it doesn't do the right thing (e.g. when the behaviour you
want is for all instances to share state) it is easy to work around. By
contrast, the behaviour you want seems to be of very limited usefulness,
and it makes it difficult to do the expected thing in almost all cases,
and work-arounds are complex and easy to get wrong.
Please don't make this about what I *want*. I don't want anything.
I just noted that one and the same reference can be processed
multiple times by the python machinery, resulting in that same
reference referencing differnt variables at the same time and
stated that that was unsane behaviour.
The standard behaviour makes it easy for objects to inherit state, and
easy for them to over-ride defaults. The behaviour(s) you and Graham want
have awkward side-effects: your proposed behaviour would mean that class
attributes would mask instance attributes, or vice versa, meaning that
the programmer would have to jump through hoops to get common types of
behaviour like inheriting state.
You don't know what I want. You only know that I have my criticism of
particular behaviour. You seem to have your idea about what the
alternative would be like, and project that to what I would want.
The behaviour you want would make it too easy to inadvertently have
instances share state. Normally we want instances to share behaviour but
have unique states -- you would change that. Why? If it is just a matter
of taste, you are welcome to your opinion. But you don't say that the
standard behaviour is "ugly", you say it is "insane", that is, irrational,
and that the behaviour you want is rational.
I called it unsane, not insane. I think I paid enough attention to never
use the word "insane", yes I once used "madness" but that was after you
were already all over me for this.

Even should I have used the word insane, I used it for a lot less than
you are implying.
That's an objective claim: please explain what makes your behaviour more
rational than the standard behaviour. Is your behaviour more useful? Does
it make code easier to write? Does it result in more compact code? What
usage cases?


What my behaviour? I don't need to specify alternative behaviour in
order to judge specific behaviour.

--
Antoon Pardon
Nov 4 '05 #84
Op 2005-11-04, Steve Holden schreef <st***@holdenwe b.com>:
Antoon Pardon wrote:
Op 2005-11-04, Steve Holden schreef <st***@holdenwe b.com>: [...]
I suppose ultimately I'm just more pragmatic than you.

It has nothing to do with being more pragmatic. Being pragmatic
is about how you handle things with real life projects. It has
little to do with the degree in which you agree with the design
of the tool you have to work with. I would say I am more pragmatic
than most defenders of python, because when it comes done to
do my work, I just use python as best as I can, while a lot
of people here seem to think that every little criticism I have
is enough to go and look for a different language.

No, being pragmatic is to do with accepting what is rather than wasting
time wishing it were otherwise,


Just accepting what is, is not pragmatic. Not much progress would have
been made if we just accepted what is.
particularly when the "insane" behavior
was actually a deliberate design choice. Which is why it doesn't work
the same as non-local references in nested scopes.


That b.a = b.a + 2

works as a result of a design choice, that I can accept.

But IMO b.a += 2, working as it does, is more the result of
earlier design and implementation decisions than it was
a deliberate design decision.

--
Antoon Pardon
Nov 4 '05 #85
Steven D'Aprano <st***@REMOVETH IScyber.com.au> writes:
There are good usage cases for the current inheritance behaviour.


Can you name one? Any code that relies on it seems extremely dangerous to me.
Nov 4 '05 #86
Antoon Pardon wrote:
Would it be too much to ask that in a line like.

x = x + 1.

both x's would resolve to the same namespace?


They always do Antoon. There is no such issue for
local (or global) varibles. The issue has to do
with c.x = c.x + 1. In this case it's clearly
designed and documented that this corresponds to:

setattr(c, 'x', getattr(c, 'x') + 1)

The result of these operations depends on e.g.
how the __setattr__ and __getattr__ methods in
the class in question are defined.

You need to understand that the dot-operaterator
always involves a lookup-operation that can be
implemented in various ways.

It's well defined that you can do things like:
class Counter: .... c=0
.... def __call__(self):
.... self.c+=1
.... def __str__(self):
.... return str(self.c)
.... c=Counter()
c()
print c 1 c()
print c 2 class C5(Counter): .... c=5
.... c5=C5()
c5()
print c5 6

Of course, you could design a language, say Pythoon
or Parthon, where this is illegal, and you force the
programmer to do something longer such as:
class APCounter:

.... c=0
.... def __init__(self):
.... self.c = self.__class__. c
.... def __call__(self):
.... self.c+=1
.... def __str__(self):
.... return str(self.c)
....

I don't see this as an improvement though...
Nov 4 '05 #87
Op 2005-11-04, Magnus Lycka schreef <ly***@carmen.s e>:
Antoon Pardon wrote:
Would it be too much to ask that in a line like.

x = x + 1.

both x's would resolve to the same namespace?
They always do Antoon. There is no such issue for
local (or global) varibles.


I meant those 'x' do be any general expression
that refers to an object. Like

a.b[c.f] = a.b[c.f] + 1
The issue has to do
with c.x = c.x + 1. In this case it's clearly
designed and documented that this corresponds to:

setattr(c, 'x', getattr(c, 'x') + 1)
The issue is with c.x += 1

Sure I find the fact that the same reference two
times in the same line can reference variable
in two different namespaces ugly.

But that one single reference refers to two
variables in two different namespaces that is
IMO more than ugly.

Suppose I have the following:

class I:
def __init__(self):
self.v = 0
def __call__(self):
t = self.v
self.v += 1
return t

i = I()
lst = range(10)
lst[i()] += 20

Nobody seems to find that this should be treated
exactly the same as
lst[i()] = lst[i()] + 20

People seem to think since lst[i()] only occurs
once, it should be only refering to one entity.

Well I think the same kind of reasoning can apply
to c.x += 1.
The result of these operations depends on e.g.
how the __setattr__ and __getattr__ methods in
the class in question are defined.

You need to understand that the dot-operaterator
always involves a lookup-operation that can be
implemented in various ways.
But there is no reason that two dot-operator are
executed when only one dot-operator is in the text.

Just as there is no reason that two i() calls
should be made when only one call is in the text.
It's well defined that you can do things like:
class Counter: ... c=0
... def __call__(self):
... self.c+=1
... def __str__(self):
... return str(self.c)
... c=Counter()
c()
print c 1 c()
print c 2 class C5(Counter): ... c=5
... c5=C5()
c5()
print c5 6

Of course, you could design a language, say Pythoon
or Parthon, where this is illegal, and you force the
programmer to do something longer such as:
class APCounter:

... c=0
... def __init__(self):
... self.c = self.__class__. c
... def __call__(self):
... self.c+=1
... def __str__(self):
... return str(self.c)
...

I don't see this as an improvement though...


Well I thought in python explicit was better than
implicit.

--
Antoon Pardon
Nov 4 '05 #88
Antoon Pardon wrote:
Op 2005-11-03, Stefan Arentz schreef <st***********@ gmail.com>:
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.

And again this argument. Like it or leave it, as if one can't in general
like the language, without being blind for a number of shortcomings.

It is this kind of recations that make me think a number of people is
blindly devoted to the language to the point that any criticism of
the language becomes intollerable.


No, it's just that a goodly number of people actually -like- the
relatively simple conceputal model of Python.

Why /shouldn't/
a.x = foo
correspond exactly to
setattr(a,'x ',foo) #?
Similarly, why shouldn't
foo = a.x
correspond exactly to
foo = getattr(a,'x') #?
With that in mind, the logical action for
a.x = f(a.x)
is
setattr(a,'x ',f(a,'x')) #,
and since
a.x += foo
is equal to
a.x = A.__iadd__(a.x, foo) # (at least for new-style classes
# that have __iadd__ defined. Otherwise, it falls back on
# __add__(self,ot her) to return a new object, making this
# evern more clear),
why shouldn't this translate into
setattr(a,'x ',A.__iadd__(ge tattr(a,'x'),fo o)) #?
Looking at it this way, it's obvious that the setattr and getattr may do
different things, if the programmer understands that "instances (can)
look up object attributes, and (always) set instance attributes." In
fact, it is always the case (so far as I can quickly check) that += ends
up setting an instance attribute. Consider this code:
class foo:
x = [5]
a = foo()
a += [6]
a.x [5,6] foo.x [5,6] foo.x = [7]
a.x

[5,6]

In truth, this all does make perfect sense -- if you consider class
variables mostly good for "setting defaults" on instances.
Nov 4 '05 #89
Steven D'Aprano wrote:
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>?


Small correction, it expands to b.a = B.a.__class__._ _iadd__(b.a,2),
assuming all relevant quantities are defined. For integers, you're
perfectly right.
Nov 4 '05 #90

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

Similar topics

106
5601
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
1930
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
2643
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
4043
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
1482
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
3448
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
9589
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
9423
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
10214
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10048
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
8872
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
7410
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
5304
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
3563
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2815
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.