Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set your subtitle preferences in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please refer to our video player troubleshooting guide for assistance.

Validating Input Values

To learn more about the concepts covered in this lesson, check out the following:

00:00 Validating Input Values. One of the most common use cases of property() is building managed attributes that validate the input data before storing or even accepting it as secure input.

00:14 Data validation is a common requirement in code that takes input from users or other information sources that you consider untrusted. Python’s property() provides a quick and reliable tool for dealing with input data validation. Thinking back to that Point example, you may require the values of .x and .y to be valid numbers.

00:36 Since your users are free to enter any type of data, you need to make sure that your Point only accepts numbers. Here’s an implementation of Point that manages this requirement.

01:05 The setter methods uses a tryexcept block that validates input data using the Python EAFP (easier to ask for forgiveness than permission) style. If the call to float() succeeds, then the input data is valid, and you get Validated! on your screen.

01:22 If float() raises a ValueError, then the user gets a ValueError with a more specific message. Note that in this code, you use the syntax raisefrom None to hide internal details related to the context in which you are raising the exception.

01:40 From the end user’s viewpoint, these details can be confusing and make your class look unpolished. Check out the section on the raise statement in the documentation for more information about this topic.

01:58 The .y property follows the same pattern as x. It’s important to note that assigning the .x and .y properties directly in .__init__() ensures that the validation also occurs during object initialization. Not doing so is a common mistake when using property() for data validation.

02:29 Here’s how the Point class works now.

02:48 If you assign .x and .y values that float() can turn into floating-point numbers, then the validation is successful, and the value is accepted.

02:57 Otherwise, you get a ValueError. This implementation of Point uncovers a fundamental weakness of property(), which you may have noticed.

03:13 You have repetitive code that follows specific patterns. This repetition breaks the DRY (Don’t Repeat Yourself) principle, so you would want to refactor this code to avoid it. To do so, you can abstract out the repetitive logic using a descriptor.

03:36 Here, you define Coordinate as a descriptor that manages your data validation in a single place.

04:22 Point now makes use of Coordinate for .x and .y.

04:37 This code works just like the earlier implementation, and you can see it being tested on-screen.

05:16 In general, if you find yourself copying and pasting property definitions all around your code, or if you spot repetitive code, then you should consider using a proper descriptor.

05:27 In the next section, you’ll see an example using computed attributes.

jchurchi on Dec. 26, 2023

I’m having a difficult time understanding what is going on in the Coordinate object with the owner and name variables. the “owner” variable doesn’t even seem to ever get used.

Bartosz Zaczyński RP Team on Jan. 2, 2024

@jchurchi Perhaps reading the written tutorial on descriptors will help you understand what’s going on in the Coordinate class better.

The owner is the class where the descriptor is used, and the name is the class variable the descriptor was assigned to. (Source)

The owner and name attributes must be declared regardless of whether they’re used or not because they’re a part of the descriptor protocol and Python provides values through those attributes when it calls your .__set_name__() method.

emru67 on March 23, 2024

It’s important to note that assigning the .x and .y properties directly in .init() ensures that the validation also occurs during object initialization. Not doing so is a common mistake when using property() for data validation.

I think that the previous ststement needs a deeper explanation or a reference to an article with a deeper explanation…I get the point but I don’t really understand it…

Become a Member to join the conversation.