Fluent Python Verse 9.6 speaks of hashable Class,
In order for the Vector2d class to be hashed, the following conditions are available:
(1) Implement __hash__ method
(2) Implement __eq__ method
(3) Make vector2d vector immutable
How do I make a vector of vector2d class instances read-only? You can use the property as follows:
classvector2d:def __init__(self, x, y): self._x=x self.__y=y @property #The @property decorator marks the getter method of a property. defx (self):returnself._x @property #The @property decorator marks the getter method of a property. defy (self):returnSelf.__y def __hash__(self):returnHash (self._x) ^ hash (self.__y) def __eq__(self, Other):returnhash (self) = =Hash (Other)def __iter__(self):return(I forIinch(Self._x, self.)__y))
We tried to modify X or Y in the console:
>>>Importexample9_7>>> V1 = example9_7.vector2d (3, 4)>>>v1.x3>>> v1.x = 4Traceback (most recent): File"<stdin>", Line 1,inch<module>Attributeerror:can'T set attribute>>> V1.Y = 5Traceback (most recent): File"<stdin>", Line 1,inch<module>Attributeerror:can'T set attribute
This is what we want to do, but why did you add the @properly adorner and become read-only? We need to have a deeper understanding of the property.
An Example to Begin with:
Before that, let's take a look at the property's application scenario:
Let's say we've written a class about temperature:
class Celsius: def __init__ (Self, temperature=0): = temperature def Get_fahrenheit (self): return self.temperature * 1.8 + 32
And this class is becoming very popular, is called by many users, one day, a user ran to suggest that the temperature should not be lower than the absolute temperature-273 degrees Celsius, he asked us to achieve this limit.
In order to achieve the user's requirements, we update to v1.1:
classCelsius:def __init__(Self, temperature=0): Self.__temperature=TemperaturedefGet_fahrenheit (self):returnSelf.__temperature* 1.8 + 32defget_temperature (self):returnSelf.__temperature defset_temperature (self, value):ifValue <-273: RaiseValueError ("temperature below-273 is not possible.") self.__temperature= value
The user's requirements are realized can have a problem here, the user's code is still the way to get the temperature:
c = Celsius (PNs)
= C.temperature
And there are hundreds of lines of code in the code that have to be changed to:
C.set_temperature () c.get_temperature ()
This is a headache for the user, because our changes are not backward compatible.
The Power of @property:
For this problem, the more pythonic solution is as follows:
1 classCelsius:2 def __init__(Self, temperature=0):3Self.__temperature=Temperature4 5 defGet_fahrenheit (self):6 returnSelf.__temperature* 1.8 + 327 8 defget_temperature (self):9 returnSelf.__temperatureTen One defset_temperature (self, value): A ifValue <-273: - RaiseValueError ("temperature below-273 is not possible.") -Self.__temperature=value the - Temprature = Property (Get_temperature, Set_temperature)
This way, users still have access to temprature as before:
>>> C1 = Property_demo. Celsius (Ten)>>> c1.temprature10>>> c1.temprature = 20>>> C1.temprature20
As a result, we have achieved both the limitations of termperature and the Guaranteed backwards compatibility
Digging deeper into property:
Python @property