我有一个包含两个属性file_path
和save_path
的对象。除非明确设置save_path
,否则我希望它与file_path
具有相同的值。
我认为执行此操作的方法是使用__setattr__
,具体如下:
class Class():
...
def __setattr__(self, name, value):
if name == 'file_path':
self.file_path = value
self.save_path = value if self.save_path == None else self.save_path
elif name == 'save_path':
self.save_path = value
但是这看起来会给我无限循环,因为只要设置了属性就会调用__setattr__
。那么,写上述内容并避免这种情况的正确方法是什么?
答案 0 :(得分:9)
首先,最简单的方法是使用属性:
<div>text</div>
其次,如果您发现自己需要撰写class Class(object):
def __init__(self, ...):
self._save_path = None
...
@property
def save_path(self):
if self._save_path is None:
return self.file_path
else:
return self._save_path
@save_path.setter
def save_path(self, val):
self._save_path = val
,则应在__setattr__
内使用super(Class, self).__setattr__
绕过__setattr__
并按正常方式设置属性,避免无限递归。
答案 1 :(得分:3)
>>> class Class:
... def __init__(self, file_path, save_path=None):
... self.file_path=file_path
... self.save_path = save_path or file_path
...
>>> c = Class('file')
>>> c.file_path
'file'
>>> c.save_path
'file'
>>> c1 = Class('file', 'save')
>>> c1.file_path
'file'
>>> c1.save_path
'save'
>>>
答案 2 :(得分:1)
使用super
!
class Class:
def __init__(self):
self.save_path = None
self.file_path = None
def __setattr__(self, name, value):
super().__setattr__(name, value)
if name == 'file_path':
super().__setattr__('save_path', self.save_path or value)
c = Class()
c.file_path = 42
print(c.file_path)
print(c.save_path)
请注意,此特定实现存在限制 - 需要首先调用self.save_path
,否则它将失败,因为调用{{时尚未设置它1}}发生,它会查找super
。
我个人可能会使用基于属性的方法。