Расширение существующего экземпляра класса в Python - PullRequest
2 голосов
/ 29 января 2020

У меня есть объект element, который возвращается другим методом класса, к которому у меня нет необходимости изменять.

>>> 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'>   

У меня есть отдельный класс, который расширяет функциональные возможности элемента.

>>> 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')

В настоящее время я использую это, передав element в класс:

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

Я хочу иметь возможность более легко получить доступ к атрибутам исходного объекта, а не к тому, чтобы укажите это в звонке. Например:

Вместо этого:

>>> input.element.tag_name
'input'

Сделайте это:

>>> input.tag_name
'input'

Как бы я реализовал что-то подобное?

1 Ответ

2 голосов
/ 30 января 2020

Вы можете преобразовать свой класс Input в прокси, реализовав метод __getattr__(), например, класс Container ниже:

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)

Вывод:

foo
BAR
name

Класс Container теперь перенаправляет любой неизвестный доступ к атрибуту своему члену contained, который, конечно, может иметь или не иметь обязательный атрибут.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...