I have defined a base class using the dataclass decorator and I want to override the setter for one of the attributes in a derived class. I tried to override the setter by implementing a method in the derived class:
from dataclasses import dataclass, field
@dataclass(repr=False, eq=False)
class SimpleUrl:
id: int # pylint: disable=invalid-name
url: str
def __eq__(self, ins: object) -> bool:
return isinstance(ins, SimpleUrl) and (self.url == ins.url)
def __iter__(self) -> iter:
return iter((self.id, self.url))
@dataclass(repr=False, eq=False)
class FullUrl(SimpleUrl):
ssl: bool = field(init=False, default=None)
@SimpleUrl.url.setter
def url(self, url: str) -> None:
self.url = url
self.ssl = url.startswith('https://')
fu = FullUrl('https://www.google.com')
print(fu.ssl)
When I try to run this example I obtain the following error message:
Exception has occurred: AttributeError
type object 'SimpleUrl' has no attribute 'url'
File "D:\projects\tests\test_urls.py", line 22, in FullUrl
@SimpleUrl.url.setter
^^^^^^^^^^^^^
File "D:\projects\tests\test_urls.py", line 18, in <module>
class FullUrl(SimpleUrl):
AttributeError: type object 'SimpleUrl' has no attribute 'url'
You can override the
__setattr__method of the derived class and in there create the desired behavior. See an example below.In this example I used the value
0for theidparameter.Returns:
In the same
__setatrr__override you could also raise an error if someone tries to change the state ofsslby hand. If you change your override to:The user can now no longer freely change the
sslvariable. If the user tries to setssl:Returns: