Should I use the `__setattr__` property or ...?

I have an object with two attributes file_pathand save_path. If save_pathnot explicitly installed, I want it to have the same meaning as file_path.

I think a way to do this with __setattr__, with something like the following:

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

But it looks like it will give me infinite loops, as it __setattr__is called whenever the attribute is set. So what is the right way to write above and avoid this?

+4
source share
3 answers

it looks sloppy. You can just use attributes. Three lines of code:

>>> 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'
>>> 
+3
source

First, the easiest way to do this is with a property:

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__, __setattr__ , .

+9

Use 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)     

Note that you must first call a constraint for this particular implementation - self.save_pathor it will fail because it is not yet set when the call occurs super, and it searches self.save_path or value.

I would probably personally use a property based approach.

+1
source

Source: https://habr.com/ru/post/1649059/


All Articles