Generally, Python just gets and sets values on attributes without any special processing just like a basic storage. But if you are implementing Page Objects where Base page class is initialized on accessing every page object class, you might need to validate the Page Object's value that's was being assigned. You may want to retrieve a value and cache it for later use.
In short, a descriptor is an attribute value that has any of the following methods:
__get__(self, instance, owner): This will be called when the attribute is retrieved (value = obj.attr), and whatever it returns is what will be given to the code that requested the attribute’s value.
__set__(): This gets called when a value is set to the attribute (obj.attr = 'value'), and shouldn’t return anything at all.
__delete__(): This is called when the attribute is deleted from an object (del obj.attr)
in the descriptor protocol. If any of those methods are defined for an attribute, it is said to be a descriptor.
Called to get the attribute of the owner class (class attribute access) or of an instance of that class (instance attribute access). An example:
class Ten:
def __get__(self, obj, objtype=None):
return 10
class A:
x = 5 # Regular class attribute
y = Ten() # Descriptor instance
a = A() # Make an instance of class A
print(a.x) # Normal attribute lookup
print(a.y) # Descriptor lookup
Prints:
5
10
Explanation: In the a.x attribute lookup, the dot operator finds 'x': 5 in the class dictionary. In the a.y lookup, the dot operator finds a descriptor instance, recognized by its get method. Calling that method returns 10. Note that the value 10 is not stored in either the class dictionary or the instance dictionary. Instead, the value 10 is computed on demand.
This usecase
As per the code in element.py
from selenium.webdriver.support.ui import WebDriverWait
class BasePageElement(object):
"""Base page class that is initialized on every page object class."""
def __set__(self, obj, value):
"""Sets the text to the value supplied"""
driver = obj.driver
WebDriverWait(driver, 100).until(lambda driver: driver.find_element_by_name(self.locator))
driver.find_element_by_name(self.locator).clear()
driver.find_element_by_name(self.locator).send_keys(value)
def __get__(self, obj, owner):
"""Gets the text of the specified object"""
driver = obj.driver
WebDriverWait(driver, 100).until(lambda driver: driver.find_element_by_name(self.locator))
element = driver.find_element_by_name(self.locator)
return element.get_attribute("value")
class Pages:
element = BasePageElement()
def __init__(self, element, value):
self.element = element # Calls __set__()
self.value = value
login_page = Pages(username, 'Henry') # Sets the username field with text Henry