我想让一个类函数知道self.var是否被它固有的子类改变了。就像C1类是P的子类一样,它改变了var的值,func改为A.当“var”没有改变时,就像C2一样,然后做B。
class P(object):
var = "original"
def func(self):
if # self.var is changed by child instance:
do A
else:
do B
class C1(P):
var = "changed"
class C2(P):
pass
c1 = C1
c2 = C2
c1.func() # do B
c2.func() # do A
由于我这样做的原因和更复杂的解释。
我需要修改openstack地平线code来填补我自己的功能:
class TabGroup(html.HTMLElement):
......
template_name = "horizon/common/_tab_group.html"
......
def render(self):
return render_to_string(self.template_name, {"tab_group": self})
TabGroup通常由其他子项继承,其中一些更改template_name,其中一些不是。我希望render方法在其子节点被其更改时知道template_name,并相应地执行不同的呈现。
答案 0 :(得分:3)
由于var
是一个类属性,您只需检查实例的值是否与父类不同:
class P(object):
var = "original"
def func(self):
if self.var != P.var:
print "DO A"
else:
print "DO B"
class C1(P):
var = "changed"
class C2(P):
pass
c1 = C1()
c2 = C2()
c1.func() # Do A
c2.func() # Do B
另一个更通用的选项可能是使用P
方法定义func
的子类,并将其用作C1
和C2
类的父类。然后,我们可以使用super来访问父属性。如下:
class P(object):
var = "original"
class PChild(P):
def func(self):
if self.var != super(PChild, self).var:
print "DO A"
else:
print "DO B"
class C1(PChild):
var = "changed"
class C2(PChild):
pass
c1 = C1()
c2 = C2()
c1.func()
c2.func()
答案 1 :(得分:2)
要告知类的属性何时更改,请使用__setattr__
魔术方法。以下是您在课堂上使用它的方法:
class AttributeCatcher(object):
def __init__(self):
# to declare without __setattr__ firing we put it directly into self.__dict__
self.__dict__['whatever'] = 'spam'
def __setattr__(self, name, value):
self.__dict__[name] = value
print('{} changed to {}'.format(name, value))
a = AttributeCatcher()
a.whatever = 'eggs'
# outputs "whatever changed to eggs"
从那里开始,创建set
以存储更改并不是一件容易的事:
class AttributeCatcher(object):
def __init__(self):
self.__dict__['whatever'] = 'spam'
self.__dict__['changes'] = set()
def __setattr__(self, name, value):
self.__dict__[name] = value
self.__dict__['changes'].add(name)
def func(self):
if 'whatever' in self.changes:
print('DO A')
else:
print('DO B')
a = AttributeCatcher()
a.whatever = 'eggs'
a.func() #outputs "DO A"
b = AttributeCatcher()
b.func() #outputs "DO B"
虽然直接把事情放到self.__dict__
会让人感觉有点笨拙,但这可以让你灵活地检查任何数量的类变量的变化。
答案 2 :(得分:1)
我认为最简单的解决方案是在类上定义一个私有变量,然后检查该值是否相同(实际上没有受到保护):
class P(object):
__private = "original"
var = __private
def func(self):
if self.var == self.__private:
do A
else:
do B
现在,这允许人们在需要时更改__private变量,但是从类外部访问它意味着它将按如下方式访问:
>>> P._P__private
'original'
>>> P._P__private = 'newvalue'
这允许您定义一个合理的起点,然后在“var”被覆盖时检查,但也允许需要的人可以覆盖该值,同时强烈建议他们不要
编辑:更新,因为带有前导下划线的方法和类变量受到保护,两个前导下划线是私有的。