Creating a Class: Getter and Setter Pattern v.s. Property
Getters
Getter and settersSetter arePattern evil.comes Evil,from evil,OOP Ilanguages say!such as C++ and Java in order to adhere to
- Encapsulation
- the bundling of data/attributes and methods.
- restricting access to implementation details and violating state invariants
In Python objectsit areis notconsidered Javaunpythonic. beans.Instead, Douse not@property writedecorator gettersinstead
Class without Getter and setters.Setter
# Basic method of setting and getting attributes in Python
# This ishas whatno Encapsulation because it directly accesses the ‘property’attributes
built-inclass isCelsius:
for.def And__init__(self, dotemperature=0):
notself.temperature take= thattemperature
todef meanto_fahrenheit(self):
thatreturn you(self.temperature should* write1.8) getters+ 32
# Create a new object
human = Celsius()
# Set the temperature
human.temperature = 37
# Get the temperature attribute
print(human.temperature)
# Get the to_fahrenheit method
print(human.to_fahrenheit())
>> 37
>> 98.60000000000001
Getter and setters,Setter andPattern then wrap them in ‘property’. That means that until you prove that you need anything more than a simple attribute access, don’t write getters and setters. They are a waste of CPU time, but more important, they are a waste of programmer time. Not just for the people writing the code and tests, but for the people who have to read and understand them as well.
- Class Attributes...
- are variables where you can access through the instance, class, or both.
- holds an internal state.
- Two ways to access class attributes:
- Directly (breaks encapsulation)
- If accessed directly, they become part of Public API
- Only use if sure that no behavior (methods) will ever be attached to the variables (@dataclass?)
- Changing implementation will be problematic:
- Converting stored attribute -> computed attribute. Want to be able to store attributes instead of recomputing each time
- No internal implementation
- Methods (ideal)
- Two methods to respect encapsulation
- Getter: Allows Access
- Setter: Allows Setting or Mutation
- Two methods to respect encapsulation
- Directly (breaks encapsulation)
- Implementation
- Making attributes Non-public
- use underscore in variable name ( _name )
- Writing Getter and Setter Methods for each attribute
- In a class, __init__ is the attributes (variables)
- Making attributes Non-public
# Making Getters and Setter methods
# PRO: Adheres to Encapsulation since get/set methods is used to change the attributes instead of direct access
# PRO: Adheres to a faux Information Hiding since converting temperature to _temperature, but no private/protected vars in Python
# CON: Has more code to change
class Celsius:
def __init__(self, temperature=0):
self.set_temperature(temperature)
def to_fahrenheit(self):
return (self.get_temperature() * 1.8) + 32
# getter method
def get_temperature(self):
return self._temperature
# setter method
def set_temperature(self, value):
if value < -273.15:
raise ValueError("Temperature below -273.15 is not possible.")
self._temperature = value
# Create a new object, set_temperature() internally called by __init__
human = Celsius(37)
# Get the temperature attribute via a getter
print(human.get_temperature())
# Get the to_fahrenheit method, get_temperature() called by the method itself
print(human.to_fahrenheit())
# new constraint implementation
human.set_temperature(-300)
# Get the to_fahreheit method
print(human.to_fahrenheit())
>> 37
>> 98.60000000000001
>> Traceback (most recent call last):
>> File "<string>", line 30, in <module>
>> File "<string>", line 16, in set_temperature
>> ValueError: Temperature below -273.15 is not possible.