1

У меня есть класс webdriver, который предполагает наличие только одного драйвера. Это плохо, потому что он не может обрабатывать сразу несколько страниц. Я хочу сделать декоратор, который будет вводить self.driver в любую функцию, украшенную, если она существует, если она не позволит какой-либо функции использовать переданный ей драйвер. Я должен быть в состоянии определить и функционировать какввод переменных в функции; python

@get_driver 
def this_func(**kwargs): 
    #I have access to 'driver' if I have self.driver or if a driver kwarg was given 

Вот он:

import os, time, subprocess, random 

from functools import wraps 

from selenium import webdriver 
from selenium.webdriver.common.keys import Keys 
from selenium.webdriver.support.select import Select 

from pyvirtualdisplay import Display 

class get_driver(object): 

    def __init__(self, func): 
     self.func = func 
     wraps(func)(self) 

    def __call__(self, *args, **kwargs): 

     try: 
      kwargs.update({'driver': self.driver}) 
     except: 
      pass 
     return_ = self.func(*args, **kwargs) 
     return return_ 

class WebdriverChauffuer(object): 

    def __init__(self, username=None, password=None, start_url=None): 
     self.username = username 
     self.password = password 
     self.start_url = start_url 

    @get_driver 
    def source_code(self, **kwargs): 
     return driver.page_source or None 

class FirefoxDriver(WebdriverChauffuer): 

    def __init__(self, username=None, password=None, start_url=None, driver=None): 
     super(FirefoxDriver, self).__init__(username=username, password=password, start_url=start_url) 

    def start_driver(self): 
     self.driver = webdriver.Firefox() 

Я получаю странные ошибки, что ни арг не было дано, хотя я называю source_code на экземпляре, который должен дать ему себя:

In [1]: from my_scripting_library import * 

In [2]: d = FirefoxDriver() 

In [3]: d.start 
d.start_driver d.start_url  

In [3]: d.start_driver() 

In [4]: d.get('https://google.com') 

In [5]: d.source_code() 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-5-7419cf5df019> in <module>() 
----> 1 d.source_code() 

/home/cchilders/scripts/my_scripting_library/webdriver/general.pyc in __call__(self, *args, **kwargs) 
    24   except: 
    25    pass 
---> 26   return_ = self.func(*args, **kwargs) 
    27   return return_ 
    28 

TypeError: source_code() takes exactly 1 argument (0 given) 

Там нет никакой разницы, когда я изменить возвращение к

return_ = self.func(**kwargs) 

Почему я не могу позвонить source_code? Спасибо

EDIT:

Эти драйверы должны быть использованы для целей, конечно, вот пример:

class HCCDriver(FirefoxDriver): 

    def __init__(self, init=False): 
     super(HCCDriver, self).__init__(start_url="https://hccadvisor.hccfl.edu") 

    def main_page(self): 
     self.get('https://www.hccfl.edu/hawknet.aspx') 

    def login_webadvisor(self, username="cchilders", password="miley_cirus_is_great_singer", driver=None): 
     self.webadvisor_driver = FirefoxDriver() 
     webadvisor_driver.get(self.start_url) 
     time.sleep(2) 
     driver.access_link(search_text="Log In") 
     driver.find_box_and_fill(search_text="LABELID_USER_NAME", value=username) 
     driver.find_box_and_fill(search_text="CURR.PWD", value=password) 
     driver.submit_form(search_text="SUBMIT") 
     driver.access_link(search_text="Students") 

    def login_email(self): 
     self.start_driver() 
     self.get("http://outlook.com/hawkmail.hccfl.edu") 
     # WebDriverWait(self.driver, 10).until(EC.presence_of_element_located(By.ID, 'ctl00_ContentPlaceHolder1_UsernameTextBox')) 
     self.find_box_and_fill(search_text="ctl00_ContentPlaceHolder1_UsernameTextBox", value="[email protected]") 
     self.find_box_and_fill(search_text="ctl00_ContentPlaceHolder1_PasswordTextBox", value="i_love_honey_booboo") 
     time.sleep(2) 
     self.submit_form("ctl00_ContentPlaceHolder1_SubmitButton") 

    def login_myhcc(self): 
     driver = FirefoxDriver() 
     driver.get("https://hcc.instructure.com") 
     time.sleep(5) 
     find_box_and_fill('ctl00_ContentPlaceHolder1_UsernameTextBox', '[email protected]') 
     driver.find_box_and_fill('ctl00_ContentPlawebadvisor_urlceHolder1_PasswordTextBox', 'if_evolution_was_real_americans_would_stop_worshipping_pres_candidates') 
     driver.click_button('ctl00$ContentPlaceHolder1$SubmitButton') 

Дело в том, без декоратора, я предвидела каждую функцию выглядит как:

def this_func(self, driver=None): 
    if not driver: 
     try: 
      driver = self.driver 
     except: 
      raise Exception('There is no driver my good sir') 

с driver=None и

try: 
     driver = self.driver 
    except: 
     raise Exception('There is no driver good sir') 

части являются повторяющимися 20, 30 раз, и т.д.

+1

где находится 'self.driver'? – Pynchia

+0

'd.start_driver()' – codyc4321

+1

В 'kwargs.update ({'driver': self.driver})' нет 'self.driver', но поскольку вы поймаете все исключения, вы подавите этот факт. – tdelaney

ответ

1

Потому что ваш декоратор реализован как класс, а не функции, ваш украшенный source_code функция не обернутый в связанном method дескриптора, так как это делается для функций , а не классы.

Это означает, что при вызове self.func, не self аргумент не передается. Но ваш метод source_code ожидает self аргумент, который приводит к ошибке source_code() takes exactly 1 argument (0 given)

На более поздних версиях Python 3, вы должны получать foo() missing 1 required positional argument: 'self' , Я не уверен, когда они добавили это разъясненное сообщение.

В комментариях приведены некоторые идеи о различных подходах, но это объясняет вашу ошибку.

+0

, так что это рефакторинг для нормального декоратора функций, который может решить эту проблему? Я все равно хотел бы реализовать его, чтобы понять, даже если он неэффективен в этом случае. – codyc4321

+1

Должен работать функциональный декоратор. Если вы хотите глубоко погрузиться и успеть, прочитайте https://github.com/GrahamDumpleton/wrapt/tree/master/blog –

Смежные вопросы