473,545 Members | 1,938 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

classmethods, class variables and subclassing

Hi,

I have a class with various class-level variables which are used to
store global state information for all instances of a class. These are
set by a classmethod as in the following (in reality the setcvar method
is more complicated than this!):

class sup(object):
cvar1 = None
cvar2 = None

@classmethod
def setcvar1(cls, val):
cls.cvar1 = val

@classmethod
def setcvar2(cls, val):
cls.cvar2 = val

@classmethod
def printcvars(cls) :
print cls.cvar1, cls.cvar2
I can then call setcvar on either instances of the class or the class
itself.

Now, the problem comes when I want to subclass this class. If I
override the setcvar1 method to do some new things special to this
class, and then call the sup.setcvar1() method, it all works fine:

class sub(sup):
cvar1a = None

@classmethod
def setcvar1(cls, val, vala):
cls.cvar1a = vala
sup.setcvar1(va l)

@classmethod
def printcvars(cls) :
print cls.cvar1a
sup.printcvars( )

This works fine, and sets cvar and cvar2 for both classes.

However, if I *don't* override the setcvar2 method, but I call
sub.setcvar2(va l) directly, then only sub.cvar2 gets set; it is no
longer identical to sup.cvar1!

In particular,
sub.setcvar1(1, 10)
sub.setcvar2(2)
sub.printcvars( )
prints
10
1 None

i.e. sub.cvar1, sub.cvar1a, sub.cvar2= 1 10 2
but sup.cvar1, cvar2= 1 None

since sup.cvar2 has never been set, and this is what sup.printcvars( )
looks for.

This behavior is "expected", but is it desirable?

For my application, at least, I think the problem really comes in the
printcvars method: is there any way to call the overridden
sup.printcvars( ) but with, effectively, cls=sub?

Thanks for reading this far!

Andrew
Andrew


This seems like a bug

Is this expected behavior, or a bug (or both -- it is expected but
probably not what is wanted!)?
Oct 20 '05 #1
12 1771
Andrew Jaffe wrote:
Hi,

I have a class with various class-level variables which are used to
store global state information for all instances of a class. These are
set by a classmethod as in the following (in reality the setcvar method
is more complicated than this!):

class sup(object):
cvar1 = None
cvar2 = None

@classmethod
def setcvar1(cls, val):
cls.cvar1 = val

@classmethod
def setcvar2(cls, val):
cls.cvar2 = val

@classmethod
def printcvars(cls) :
print cls.cvar1, cls.cvar2
I can then call setcvar on either instances of the class or the class
itself.

Now, the problem comes when I want to subclass this class. If I
override the setcvar1 method to do some new things special to this
class, and then call the sup.setcvar1() method, it all works fine:

class sub(sup):
cvar1a = None

@classmethod
def setcvar1(cls, val, vala):
cls.cvar1a = vala
sup.setcvar1(va l)

@classmethod
def printcvars(cls) :
print cls.cvar1a
sup.printcvars( )

This works fine, and sets cvar and cvar2 for both classes.

However, if I *don't* override the setcvar2 method, but I call
sub.setcvar2(va l) directly, then only sub.cvar2 gets set; it is no
longer identical to sup.cvar1!

In particular,
sub.setcvar1(1, 10)
sub.setcvar2(2)
sub.printcvars( )
prints
10
1 None

i.e. sub.cvar1, sub.cvar1a, sub.cvar2= 1 10 2
but sup.cvar1, cvar2= 1 None

since sup.cvar2 has never been set, and this is what sup.printcvars( )
looks for.

This behavior is "expected", but is it desirable?

For my application, at least, I think the problem really comes in the
printcvars method: is there any way to call the overridden
sup.printcvars( ) but with, effectively, cls=sub?

Thanks for reading this far!

Andrew
Andrew


This seems like a bug

Is this expected behavior, or a bug (or both -- it is expected but
probably not what is wanted!)?


You are experiencing this problem because you are using hard-wired class
names. Try using (for example) self.__class__. That way, even if your
method is inheroted by a subclass it will use the class of the object it
finds itself a method of. No need to use classmethods.

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/

Oct 20 '05 #2
> Andrew Jaffe wrote:
Hi,

I have a class with various class-level variables which are used to
store global state information for all instances of a class. These are
set by a classmethod as in the following

class sup(object):
cvar1 = None
cvar2 = None

@classmethod
def setcvar1(cls, val):
cls.cvar1 = val

@classmethod
def setcvar2(cls, val):
cls.cvar2 = val

@classmethod
def printcvars(cls) :
print cls.cvar1, cls.cvar2

Now, the problem comes when I want to subclass this class. If I
override the setcvar1 method to do some new things special to this
class, and then call the sup.setcvar1() method, it all works fine:

class sub(sup):
cvar1a = None

@classmethod
def setcvar1(cls, val, vala):
cls.cvar1a = vala
sup.setcvar1(va l)

@classmethod
def printcvars(cls) :
print cls.cvar1a
sup.printcvars( )

This works fine, and sets cvar and cvar2 for both classes.

However, if I *don't* override the setcvar2 method, but I call
sub.setcvar2(va l) directly, then only sub.cvar2 gets set; it is no
longer identical to sup.cvar1!

In particular,
sub.setcvar1(1, 10)
sub.setcvar2(2)
sub.printcvars( )
prints
10
1 None

i.e. sub.cvar1, sub.cvar1a, sub.cvar2= 1 10 2
but sup.cvar1, cvar2= 1 None

This behavior is "expected", but is it desirable?


You are experiencing this problem because you are using hard-wired class
names. Try using (for example) self.__class__. That way, even if your
method is inheroted by a subclass it will use the class of the object it
finds itself a method of. No need to use classmethods.


The problem is that I actually do want to call these methods on the
class itself, before I've made any instances.

A
Oct 21 '05 #3
Andrew Jaffe wrote:
Andrew Jaffe wrote:

Hi,

I have a class with various class-level variables which are used to
store global state information for all instances of a class. These are
set by a classmethod as in the following

class sup(object):
cvar1 = None
cvar2 = None

@classmethod
def setcvar1(cls, val):
cls.cvar1 = val

@classmethod
def setcvar2(cls, val):
cls.cvar2 = val

@classmethod
def printcvars(cls) :
print cls.cvar1, cls.cvar2

Now, the problem comes when I want to subclass this class. If I
override the setcvar1 method to do some new things special to this
class, and then call the sup.setcvar1() method, it all works fine:

class sub(sup):
cvar1a = None

@classmethod
def setcvar1(cls, val, vala):
cls.cvar1a = vala
sup.setcvar1(va l)

@classmethod
def printcvars(cls) :
print cls.cvar1a
sup.printcvars( )

This works fine, and sets cvar and cvar2 for both classes.

However, if I *don't* override the setcvar2 method, but I call
sub.setcvar2 (val) directly, then only sub.cvar2 gets set; it is no
longer identical to sup.cvar1!

In particular,
sub.setcvar1(1, 10)
sub.setcvar2(2)
sub.printcvars( )
prints
10
1 None

i.e. sub.cvar1, sub.cvar1a, sub.cvar2= 1 10 2
but sup.cvar1, cvar2= 1 None

This behavior is "expected", but is it desirable?


You are experiencing this problem because you are using hard-wired class
names. Try using (for example) self.__class__. That way, even if your
method is inheroted by a subclass it will use the class of the object it
finds itself a method of. No need to use classmethods.

The problem is that I actually do want to call these methods on the
class itself, before I've made any instances.

I see. I think. So what you are saying is that when you call
sup.printcvars( ) from inside a sub method you want it to see the
namespace of the sub class not the sup?

Since you have set all this up carefully you must have a use case, but
it seems a little contorted (to me). Basically you appear to want the
classes to behave statically the way that instances do dynamically?

Not sure I can help you here.

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/

Oct 21 '05 #4
Andrew Jaffe wrote:
Andrew Jaffe wrote:
[...]
The problem is that I actually do want to call these methods on the
class itself, before I've made any instances.

Except you could use staticmethods with an explicit class argument ...

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/

Oct 21 '05 #5
Steve Holden wrote:
Andrew Jaffe wrote:
The problem is that I actually do want to call these methods on the
class itself, before I've made any instances.

Except you could use staticmethods with an explicit class argument ...


Steve,

Yep, that would work! Thanks.

But it does seem like a bit of a kludge: classmethods seems to be almost
exactly what you 'ought' to use here (i.e., I really do want to apply
these methods to the class as an object in its own right).

A

Oct 21 '05 #6
Andrew Jaffe wrote:
Steve Holden wrote:
Andrew Jaffe wrote:

The problem is that I actually do want to call these methods on the
class itself, before I've made any instances.


Except you could use staticmethods with an explicit class argument ...

Steve,

Yep, that would work! Thanks.

But it does seem like a bit of a kludge: classmethods seems to be almost
exactly what you 'ought' to use here (i.e., I really do want to apply
these methods to the class as an object in its own right).

What's the use case?

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/

Oct 21 '05 #7
Steve Holden wrote:
Andrew Jaffe wrote:
Steve Holden wrote:
Andrew Jaffe wrote:

The problem is that I actually do want to call these methods on the
class itself, before I've made any instances.

Except you could use staticmethods with an explicit class argument ...


Yep, that would work! Thanks.

But it does seem like a bit of a kludge: classmethods seems to be
almost exactly what you 'ought' to use here (i.e., I really do want to
apply these methods to the class as an object in its own right).

What's the use case?


Fair question. I hope the following isn't too technical.

I have a class which describes the model for fitting some data,
encapsulating among other things a bunch of parameters whose values I'd
like to determine for a given dataset. The base class is a simple model,
the derived class a slightly more complicated one with an extra parameter.

At present, I instantiate the class with a particular set of values for
the parameters.

One of the methods in this class is called 'prior', which returns the
prior probability for the instance's paramters.

However, it turns out there are some 'meta-parameters' which don't
change between instances, in particular the allowed limits on the
parameters, beyond which the prior should return 0. Currently these are
stored as class variables -- so both the base and derived class want to
be able to act as if these class variables are 'native' to their own
class -- since in fact the base/derived relationship is in this case
actually something of an implementation detail. (Currently I've solved
the problem by explicitly using the base class methods for setting the
class variables.)

Does this make sense?

Andrew

Oct 21 '05 #8
Andrew Jaffe wrote:
Steve Holden wrote:
Andrew Jaffe wrote:
Steve Holden wrote:

Andrew Jaffe wrote:
>The problem is that I actually do want to call these methods on the
>class itself, before I've made any instances.
>

Except you could use staticmethods with an explicit class argument ...

Yep, that would work! Thanks.

But it does seem like a bit of a kludge: classmethods seems to be
almost exactly what you 'ought' to use here (i.e., I really do want to
apply these methods to the class as an object in its own right).


What's the use case?

Fair question. I hope the following isn't too technical.

I have a class which describes the model for fitting some data,
encapsulating among other things a bunch of parameters whose values I'd
like to determine for a given dataset. The base class is a simple model,
the derived class a slightly more complicated one with an extra parameter.

At present, I instantiate the class with a particular set of values for
the parameters.

One of the methods in this class is called 'prior', which returns the
prior probability for the instance's paramters.

However, it turns out there are some 'meta-parameters' which don't
change between instances, in particular the allowed limits on the
parameters, beyond which the prior should return 0. Currently these are
stored as class variables -- so both the base and derived class want to
be able to act as if these class variables are 'native' to their own
class -- since in fact the base/derived relationship is in this case
actually something of an implementation detail. (Currently I've solved
the problem by explicitly using the base class methods for setting the
class variables.)

Does this make sense?


I think so. It's not normal adive, but it sounds like a metaclass might
be what you need here.

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/

Oct 21 '05 #9
Steve Holden wrote:
[...]

I think so. It's not normal adive, but it sounds like a metaclass might
be what you need here.

^adive^advice^

spell-me-own-name-wrong-next-ly y'rs - evest
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.python.org/pycon/

Oct 21 '05 #10

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

Similar topics

0
1376
by: Paul Morrow | last post by:
Probably the best-loved features of Python are the shortcuts. The fact that you don't have to explicitly declare very much and that the language supports clear, shorthand syntax for frequently used operations... x = y = r def __foo():
9
4595
by: jfj | last post by:
Hi. Suppose this: ######################## def foo (x): print x f = classmethod (foo)
3
2419
by: syd | last post by:
Hello all, In my project, I have container classes holding lists of item classes. For example, a container class myLibrary might hold a list of item classes myNation and associated variables like myNation.name='USA' and myNation.continent='North America'. Bottom line, I was hoping to use this structure to marshal the classes to xml.
12
3095
by: titan nyquist | last post by:
I have a class with data and methods that use it. Everything is contained perfectly THE PROBLEM: A separate thread has to call a method in the current instantiation of this class. There is only ever ONE instantiation of this class, and this outside method in a separate thread has to access it. How do i do this?
15
2534
by: =?Utf-8?B?UGF0Qg==?= | last post by:
Just starting to move to ASP.NET 2.0 and having trouble with the Global.asax code file. In 1.1 I could have a code behind file for the global.asax file. This allow for shared variables of the Global class. Note: I use these shared variables for read only values that are set at application start. It would appear the 2.0 doesn't like you...
2
1207
by: Steven D'Aprano | last post by:
There's some subtle behaviour going on here that I don't really follow. Class methods apparently aren't classmethods. .... def method(self, *args): .... return self, args .... @classmethod .... def cmethod(cls, *args): .... return cls, args ....
7
1725
by: Ivan Illarionov | last post by:
After re-reading "Python is not Java" I finally came to conclusion that classmethods in Python are a very Bad Thing. I can't see any use-case of them that couldn't be re-written more clearly with methods of metaclass or plain functions. They have the following issues: 1. You mix instance-level and class-level functionality in one place...
5
2509
by: Ray | last post by:
Hi all, I am thinking of subclassing the standard string class so I can do something like: mystring str; .... str.toLower (); A quick search on this newsgroup has found messages by others
1
8790
by: xamalek | last post by:
I was thinking that when you override a struct variable when you are subclassing the struct, then the variable in the new struct would stomp on the old one ... (i.e.) the parent variable (i) and the subclass variable (i) would share the same pointer ... however I was wrong, and I want to understand this better. The question is: When you...
0
7656
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. ...
0
7807
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...
1
7419
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
7756
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...
1
5326
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...
0
4944
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...
0
3450
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...
0
3442
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1014
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.