classmethods,类变量和子类 [英] classmethods, class variables and subclassing

查看:60
本文介绍了classmethods,类变量和子类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




我有一个包含各种类级别变量的类,用于
存储类的所有实例的全局状态信息。这些是由类方法设置的

,如下所示(实际上setcvar方法

比这更复杂!):


class sup(对象):

cvar1 =无

cvar2 =无


@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

然后我可以在类或类的实例上调用setcvar

本身。


现在,问题出现在我想要继承这个类的时候。如果我用
覆盖setcvar1方法来为这个

类做一些特别新的事情,然后调用sup.setcvar1()方法,一切正常:


class sub(sup):

cvar1a =无


@classmethod

def setcvar1(cls,val,vala):

cls.cvar1a = vala

sup.setcvar1(val)


@classmethod

def printcvars(cls):

print cls.cvar1a

sup.printcvars()


这样工作正常,并为两个类设置cvar和cvar2。


但是,如果我*不要*覆盖setcvar2方法,但我打电话给
$ b直接$ b sub.setcvar2(val),然后只设置sub.cvar2;它没有

与sup.cvar1相同的长度!


特别是,

sub.setcvar1(1,10)< br $>
sub.setcvar2(2)

sub.printcvars()

打印

10

1无


即sub.cvar1,sub.cvar1a,sub.cvar2 = 1 10 2

但sup.cvar1,cvar2 = 1无<因为sup.cvar2从未设置过,所以
,这就是sup.printcvars()

所寻找的。


这种行为是预期的,但它是否可取?


对于我的应用程序,至少,我认为问题确实来自

printcvars方法:有没有办法调用被覆盖的

sup.printcvars()但是,有效地,cls = sub?


感谢你阅读这篇文章!


安德鲁

安德鲁



这似乎是一个bug


这是预期的行为,还是一个错误(或者两者兼而有之 - 这是预期的但是

可能不是想要的!)?
解决方案

Andrew Jaffe写道:



我有一个包含各种类级别变量的类用于存储类的所有实例的全局状态信息。这些是由类方法设置的,如下所示(实际上setcvar方法比这更复杂!):

类sup(对象):
cvar1 =无
cvar2 =无

@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

然后我可以在类或类本身的任何一个实例上调用setcvar。

现在,问题出现在我想要子类的时候这个班。如果我重写setcvar1方法来为这个
类做一些特别新的事情,然后调用sup.setcvar1()方法,一切正常:

class sub (sup):
cvar1a =无

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

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

这个工作正常,并为两个类设置cvar和cvar2。

但是,如果我*不要*覆盖setcvar2方法,但我直接调用
sub.setcvar2(val),然后只有sub.cvar2被设置;它与sup.cvar1相比没有更长的时间!

特别是,
sub.setcvar1(1,10)
sub.setcvar2(2) sub.printcvars()
打印
10


即sub.cvar1,sub.cvar1a,sub.cvar2 = 1 10 2
但是sup.cvar1,cvar2 = 1没有

因为sup.cvar2从未设置过,这就是sup.printcvars()
所寻求的。

这种行为是预期的,但它是否可取?

对于我的应用程序,至少,我认为问题确实来自
printcvars方法:有没有办法调用覆盖了
sup.printcvars()但有效地,cls = sub?

感谢您阅读这篇文章!

Andrew

安德鲁

这似乎是一个错误

这是预期的行为,还是一个错误(或两者兼而有之 - 它是预期的但是
可能不是什么需要!)?




您遇到此问题,因为您使用的是硬连线lass

名字。尝试使用(例如)self .__ class__。这样,即使你的子类继承你的

方法,它也会使用对象的类。

发现自己是一个方法。无需使用classmethods。


问候

Steve

-

Steve Holden +44 150 684 7255 +1 800 494 3119

Holden Web LLC www.holdenweb.com

PyCon TX 2006 www.python.org/ pycon /


> Andrew Jaffe写道:



我有一个包含各种类级变量的类,用于存储全局所有类实例的状态信息。这些是由类方法设置的,如下面的

类sup(对象):
cvar1 =无
cvar2 =无

@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

现在问题来了我想继承这个类。如果我重写setcvar1方法来为这个
类做一些特别新的事情,然后调用sup.setcvar1()方法,一切正常:

class sub (sup):
cvar1a =无

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

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

这个工作正常,并为两个类设置cvar和cvar2。

但是,如果我*不要*覆盖setcvar2方法,但我直接调用
sub.setcvar2(val),然后只有sub.cvar2被设置;它与sup.cvar1相比没有更长的时间!

特别是,
sub.setcvar1(1,10)
sub.setcvar2(2) sub.printcvars()
打印
10


即sub.cvar1,sub.cvar1a,sub.cvar2 = 1 10 2
但是sup.cvar1,cvar2 = 1没有

这种行为是预期的,但它是否可取?



你遇到了这个问题,因为你是使用硬连线类名称。尝试使用(例如)self .__ class__。这样,即使你的
方法被子类继承,它也会使用它自己发现自己的方法的对象的类。不需要使用classmethods。




问题是我确实想在

类本身之前调用这些方法已经做了任何实例。


A


Andrew Jaffe写道:

Andrew Jaffe写道:



我有一个类,有各种类级变量,用于
存储类的所有实例的全局状态信息。这些是由类方法设置的,如下面的

类sup(对象):
cvar1 =无
cvar2 =无

@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

现在问题来了我想继承这个类。如果我重写setcvar1方法来为这个
类做一些特别新的事情,然后调用sup.setcvar1()方法,一切正常:

class sub (sup):
cvar1a =无

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

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

这个工作正常,并为两个类设置cvar和cvar2。

但是,如果我*不要*覆盖setcvar2方法,但我直接调用
sub.setcvar2(val),然后只有sub.cvar2被设置;它与sup.cvar1相比没有更长的时间!

特别是,
sub.setcvar1(1,10)
sub.setcvar2(2) sub.printcvars()
打印
10
1无

ie sub.cvar1,sub.cvar1a,sub.cvar2 = 1 10 2
但sup.cvar1,cvar2 = 1无

此行为是预期的,但它是否可取?



您遇到此问题是因为您使用的是硬连线类名称。尝试使用(例如)self .__ class__。这样,即使你的
方法被子类继承,它也会使用它自己发现自己的方法的对象的类。不需要使用classmethods。



问题是我确实想在我做任何实例之前在
类本身上调用这些方法。



我明白了。我认为。所以你要说的是当你从子方法中调用

sup.printcvars()时,你希望它看到子类的

命名空间而不是sup ?


因为你已经仔细设置了所有这些,你必须有一个用例,但

似乎有点扭曲(对我来说)。基本上你似乎想要

类静态地表现实例动态的方式吗?


不确定我能在这里帮助你。
< br $>
问候

Steve

-

Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com

PyCon TX 2006 www.python.org/pycon/


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(val)

@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

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!)?

解决方案

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(val)

@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

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/


> 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(val)

@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.

A


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(val)

@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/


这篇关于classmethods,类变量和子类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆