属性设置器在Python类中不起作用
我正在使用一个我无法控制的类(MainClass)。我想将我的类建立在MainClass的基础上,但要添加额外的功能。我在类(超类)中添加了一个属性(索引),但当我尝试将索引转换为属性时,@.setter似乎被忽略。这里怎么了属性设置器在Python类中不起作用,python,oop,properties,Python,Oop,Properties,我正在使用一个我无法控制的类(MainClass)。我想将我的类建立在MainClass的基础上,但要添加额外的功能。我在类(超类)中添加了一个属性(索引),但当我尝试将索引转换为属性时,@.setter似乎被忽略。这里怎么了 class MainClass(object): def __init__(self): self.name = 'abc' class SuperClass(object): def __init__(self, main, *args
class MainClass(object):
def __init__(self):
self.name = 'abc'
class SuperClass(object):
def __init__(self, main, *args, **kwargs):
super(SuperClass, self).__init__(*args, **kwargs)
self.__main = main
self._index = 0
def __getattr__(self, attr):
return getattr(self.__main, attr)
def __setattr__(self, attr, val):
if attr == '_SuperClass__main':
object.__setattr__(self, attr, val)
return setattr(self.__main, attr, val)
@property
def index(self):
return self._index
@index.setter
def index(self, value):
self._index = value
main_object = MainClass()
super_object = SuperClass(main_object)
print('x', super_object.index, super_object.name)
super_object.index = 3
print('y', super_object.index)
super_object.index += 2
print('z', super_object.index)
您定义的
\uuuu setattr\uuuu
方法优先于@index.setter
简化代码,它应该可以工作:
class MainClass(object):
def __init__(self):
self.name = 'abc'
class SuperClass(object):
def __init__(self, main, *args, **kwargs):
super(SuperClass, self).__init__(*args, **kwargs)
self.__main = main
self._index = 0
@property
def name(self):
return self.__main.name
@name.setter
def name(self):
return self.__main.name
@property
def index(self):
return self._index
@index.setter
def index(self, value):
self._index = value
main_object = MainClass()
super_object = SuperClass(main_object)
print('x', super_object.index, super_object.name)
super_object.index = 3
print('y', super_object.index)
super_object.index += 2
print('z', super_object.index)
输出:
x 0 abc
y 3
z 5
\uuuu getattr\uuuu
仅在正常查找机制失败时使用
但是,所有设置属性的尝试都会调用\uuuuuu setattr\uuuuu
。这意味着您当前的定义将在
MainClass
实例,而不是访问属性的setter
>>> super_object._SuperClass__main.index
2
由于\uuuu setattr\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
\uuuu setattr\uuuu
必须处理三种情况:
属性\u SuperClass\uuuuu main
本身,用于在\uuuu init\uuuu
中指定给self.\uuuuu main
时
分配给self.\uu main
指定给特定于超类的属性
记住这一点,试试看
def __setattr__(self, attr, val):
if attr == '_SuperClass__main':
super().__setattr__(attr, val)
elif hasattr(self.__main, attr):
setattr(self.__main, attr, val)
else:
super().__setattr__(attr, val)
我还建议使用更简单的选项,即仅从MainClass
继承,而不是使用组合和委派:
class SuperClass(MainClass):
def __init__(self):
super().__init__()
self._index = 0
@property
def index(self):
return self._index
@index.setter
def index(self, value):
self._index = value
谢谢我可以看出这是可行的,但这意味着我必须为MainClass中的所有属性设置属性和setter。这不是小事。没有办法吗?我喜欢setattr和getattr,因为它可以解决这个问题。这不是我能想到的。我还没有设法使属性.setter
和\uuuu setattr\uuuu
很好地协同工作。不管怎样,只使用属性是更干净的。你有没有理由不从Main
继承SuperClass
?谢谢,但这对我不起作用(我想)。我看到了MainClass对象,要创建超类对象,我必须分配所有属性(不是吗?)。那会破坏目标的