2

I have an object element that is returned by another class method I don't necessarily have access to change.

>>> from selenium.webdriver import Chrome
>>> browser = Chrome()
>>> browser.get('https://www.google.com')
>>> element = driver.find_element_by_tag_name('input')
>>> type(element)
<class 'selenium.webdriver.remote.webelement.WebElement'>   

I have a separate class that extends the functionality of the element.

>>> class Input:
>>>     def __init__(self, element):
>>>         assert element.tag_name == 'input', 'Element must be of type "input"'
>>>         self.element = element
>>>         self.browser = element.parent
>>>     def is_enabled(self):
>>>         return self.element.is_enabled()
>>>     @property
>>>     def value(self):
>>>         return self.element.get_attribute('value')

Currently the way I use this is by passing element into the class:

>>> input = Input(element)
>>> input.is_enabled() # Same as input.element.is_enabled()
True

I want to be able to more easily access the original object's attributes rather than having to specify it in the call. For example:

Instead of this:

>>> input.element.tag_name
'input'

Do this:

>>> input.tag_name
'input'

How would I implement something like this?

2
  • 2
    You need the proxy pattern. You can forward attribute accesses to the contained element.
    – quamrana
    Commented Jan 29, 2020 at 20:48
  • Could you clarify a bit further? Commented Jan 29, 2020 at 20:53

1 Answer 1

2

You can convert your Input class to be a proxy by implementing the __getattr__() method, like the Container class below:

class Example:
    def __init__(self):
        self.tag_name = 'name'
    def foo(self):
        return 'foo'
    def bar(self, param):
        return param

class Container:
    def __init__(self, contained):
        self.contained = contained

    def zoo(self):
        return 0

    def __getattr__(self, item):
        if hasattr(self.contained, item):
            return getattr(self.contained,item)
        #raise item

c = Container(Example())
print(c.foo())
print(c.bar('BAR'))
print(c.tag_name)

Output:

foo
BAR
name

The Container class now forwards any unknown attribute accesses to its contained member, which of course, may or may not have the required attribute.

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.