Переименуйте метод класса внешнего модуля - PullRequest
0 голосов
/ 25 октября 2018

Вопрос:

Как переименовать метод (функцию), существующий в импортированном классе модулей?

Общая идея:

#Current Generalized Code
from module import myImportedClass
X = myImportedClass.some_very_long_method_name_that_exists(*args).another_method(*args)

#Becomes Shorter Code
X = myImportedClass.SVLM(*args).AM(*args)

Конкретный пример:

У меня есть несколько скриптов, которые работают, но я бы хотел стилистически переписать длинные строки кода в стиле PEP8.Одна повторяющаяся проблема, с которой я сталкиваюсь - это подробные имена методов (особенно из модуля веб-драйвера Selenium), импортированный класс модулей.

Ниже приведен отрывок, который передает то, что я хотел бы сделать.Однако после поиска я не совсем уверен, как этого достичь.Нужно ли мне писать какой-то локальный класс / функцию в моем скрипте Python, который позволяет псевдониму вести себя как оригинальное имя метода?

#Current Example with Long Imported Class Method Names
from selenium import webdriver
d = webdriver.Firefox()


def load_job_cards(counter, job_key, job_type, filestem='newjobs'):

    posts = d.find_elements_by_xpath("//div[@class='  row  result clickcard']")
    job_names = [j.find_element_by_css_selector("a[class='turnstileLink']").get_attribute('title') for j in posts]

    #...more code...


#Would Like Imported Class Method to be Renamed, e.g.:
def load_job_cards(counter, job_key, job_type, filestem='newjobs'):

    posts = d.find_elements_by_xpath("//div[@class='  row  result clickcard']")
    job_names = [j.fcss("a[class='turnstileLink']").ga('title') for j in posts]

    #...more code...

Для справки, импортированные методы класса WebDriver описаны в следующемсценарий:

https://github.com/SeleniumHQ/selenium/blob/18681a6c1b59434f2639c2c56383a58f1118f009/py/selenium/webdriver/firefox/webdriver.py

Ответы [ 3 ]

0 голосов
/ 25 октября 2018

Вы можете наследовать от myImportedClass и определить новый метод:

class MyNewClass(myImportedClass):
    def SVLM(self, *args):
        return self.another_method(args)

Тогда вы можете сделать

from some_module import MyNewClass

MyNewClass(ARGS).SVLM(ARGS2)

В соответствии с вашим примером, обратите внимание, что find_element_by_css_selector является методомWebDriver, в то время как get_attribute является методом WebElement, поэтому вам нужно обновить два класса ...

НО !если вам действительно нужно сделать строки более короткими, а код - более читабельным, не спешите делать это.Новые имена классов и методов могут сбить с толку людей, которые будут использовать / поддерживать ваш код.

Я предлагаю вам просто изменить свой код, как показано ниже:

post_locator = "xpath", "//div[@class='  row  result clickcard']"
link_locator = "css", "a[class='turnstileLink']"

def load_job_cards(counter, job_key, job_type, filestem='newjobs'):

    posts = d.find_elements(*post_locator)
    job_names = [j.find_element(*link_locator).get_attribute('title') for j in posts]

PS Обратите внимание, что отделяя локаторы элементов от исполнительный код - это основа паттерна PageObject, поэтому он все равно не будет лишним

0 голосов
/ 25 октября 2018

Основываясь на предложении @Ashish Kamble о функциональных указателях, я нашел несколько решений для моего конкретного случая.Я до сих пор не понял, как переименовать функции, чтобы наследовать исходные атрибуты class.method от существующих веб-элементов, например j.fcss("a[class='turnstileLink']").ga('title').

Решение исходной проблемы с другой функцией, однако я получаю:

from selenium import webdriver
d = webdriver.Firefox()


def find_css(element, css):
    return element.find_element_by_css_selector(css)


def load_job_cards(counter, job_key, job_type, filestem='newjobs'):

    posts = d.find_elements_by_xpath("//div[@class='  row  result clickcard']")

    #Breaking the Long Line with the New Function
    css = "a[class='turnstileLink']"
    job_names = [find_css(j, css).get_attribute('title') for j in posts]


    #Other Code Where This is Also Useful
    companies = [find_css(c, "span[class='company']").text for c in posts]
    locations = [find_css(l, "span[class='location']").text for l in posts]

job_names = [slvm2(j, css, ga) for j in posts]
#Alt Solution 1
def find_css(element, css):
    return element.find_element_by_css_selector(css)


def ga(element, attribute):
    return element.get_attribute(attribute)


def load_job_cards(counter, job_key, job_type, filestem='newjobs'):

    posts = d.find_elements_by_xpath("//div[@class='  row  result clickcard']")

    css = "a[class='turnstileLink']"
    job_names = [ga(find_css(j, css), 'title') for j in posts]



#Alt Solution 2 (Less Generalizable)
def SVLM(j, css, ga):
    return j.find_element_by_css_selector(css).get_attribute(ga)


def load_job_cards(counter, job_key, job_type, filestem='newjobs'):

    posts = d.find_elements_by_xpath("//div[@class='  row  result clickcard']")

    css = "a[class='turnstileLink']"
    job_names = [SVLM(j, css, 'title') for j in posts]
0 голосов
/ 25 октября 2018

Я не знаю, как переименовать, но здесь можно использовать небольшой трюк с использованием функциональных указателей, сохранить полную функцию в переменной, а затем вызвать новую функцию.

newFunName =  Package.Module.Function 
newFunName()

Надеюсь, это поможет вам

from module import myImportedClass
def do(ar) myImportedClass.some_very_long_method_name_that_exists(ar).another_method(ar)

становится более коротким, вызывая код

X = do(**args)
...