Write a program using an object
Start to create your object-oriented text-based adventure game
Extend other people’s classes
Create an enemy in the room
Recap Week 3
Extending your knowledge of OOP
Finish your game
End of the course
A property is a special type of function that allows you to get and set attributes without the use of getter and setter methods.
Many programming languages, including Python, support properties, although some languages, such as C++ and Java, do not.
As you have previously learnt, it is good practice to set attributes through the use of getter and setter methods, as demonstrated in this class:
class MyClass():
def __init__(self):
self.my_attribute = 0
def get_my_attribute(self):
return self.my_attribute
def set_my_attribute(self, value):
self.my_attribute = value
my_object = MyClass()
my_object.set_my_attribute(1)
print(my_object.get_my_attribute())
As the attributes are public, it is possible in Python to access them directly using my_object.my_attribute, for example:
my_object = MyClass()
my_object.my_attribute = 2
print(my_object.my_attribute)
This approach would simplify the code, but with the downside that without wrapping the get and set into functions, you cannot control how attributes in your class are updated. There would be nothing stopping someone setting the attribute to an invalid value, for example:
my_object.my_attribute = "some invalid value"
Properties get around this problem by allowing you to define a function that is called when the value of an attribute is changed directly.
I have modified the example class above to use a property instead of a getter and setter.
class MyClass():
def __init__(self):
self._my_attribute = 0
@property
def my_attribute(self):
return self._my_attribute
@my_attribute.setter
def my_attribute(self, value):
self._my_attribute = value
my_object = MyClass()
Walking through this code, you can see the following changes:
I have used an underscore _ to denote that the my_attribute attribute is protected. By doing so I am stating that this attribute should not be changed directly.
There are two new methods, both called my_attribute.
The my_attribute method that has the @property decorator before it is the getter and, when called, it will return the value stored in _my_attribute.
The second my_attribute method that has the @my_attribute.setter decorator is the setter. It accepts a single parameter which, when called, will set _my_attribute to the value passed.
To get the attribute you use the getter property method name, just as you would have for a normal attribute.
the_value = my_object.my_attribute
This calls the getter property method and returns the value of the object’s _my_attribute attribute.
@property
def my_attribute(self):
return self._my_attribute
To set the attribute, you assign a value to the setter property.
my_object.my_attribute = 3
In the setter property, the value being assigned (3 in this case) will be passed as the value parameter:
@my_attribute.setter
def my_attribute(self, value):
self._my_attribute = value
The advantage of properties is that you can maintain the simple syntax of object.attribute, but a function is being used behind the scenes. This can be useful for tasks such as validation.
For example, you could modify the setter property to validate that the value being set is a positive number:
@my_attribute.setter
def my_attribute(self, value):
if value < 0:
print("Invalid value")
else:
self._my_attribute = value
Conversely, you could use the getter to modify the data before it was returned, for example by always returning the attribute value as a string:
@property
def my_attribute(self):
string_attribute = str(self._my_attribute)
return string_attribute
Modify one of the classes from your game to use properties rather than getter and setter methods. Share your solutions using Pastebin, provide the URL in the comments section, and include how you chose which class to modify and how you approached the problem.