【问题标题】:Rename an External Module Class Method重命名外部模块类方法
【发布时间】:2019-03-29 14:39:29
【问题描述】:

问题:

如何重命名已导入模块类中存在的方法(函数)?

总体思路:

#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 webdriver 模块),一个导入的模块类。

下面是一段摘录,表达了我想做的事情。然而,经过搜索,我不确定如何实现这一目标。我是否需要在我的 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

【问题讨论】:

  • 我已经意识到在一般示例中需要额外的细微差别(这在特定示例中可能很明显)。虽然很长的方法名称 find_element_by_css_selector(*arg) 是模块 webdriver 的一个方法,但该方法需要适用于帖子的每个元素,它本身是在 webdriver 上执行的另一个方法的 Web 元素。

标签: python python-3.x selenium class methods


【解决方案1】:

我不知道如何重命名,但在这里使用功能指针只需一个小技巧, 将完整函数存储在变量中,然后调用新函数。

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)

【讨论】:

  • 感谢函数指针的想法。我必须修改您的示例以使其与我的代码一起使用(上面的示例)。
【解决方案2】:

您可以从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_selectorWebDriver 的方法,而get_attributeWebElement 的方法,因此您需要更新两个类...

但是!如果你真的需要让你的行更短并且你的代码更具可读性,不要急于去做。新的类和方法名称可能会让使用/维护您的代码的人感到困惑。

我建议你只修改你的代码如下:

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]

附:请注意,将元素定位器与 执行代码 代码分开是 PageObject 模式的基础,因此无论如何都不会是多余的

【讨论】:

  • 谢谢! 实际上,我从未见过这样的做法,即分隔元素定位器或X = type, pattern,然后在代码中使用*X 引用它。太棒了。
【解决方案3】:

根据@Ashish Kamble 对功能指针的建议,我为我的具体情况找到了一些解决方案。我还没有弄清楚如何重命名函数以继承现有 web 元素上的原始 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]

【讨论】:

    猜你喜欢
    • 2020-04-05
    • 1970-01-01
    • 1970-01-01
    • 2015-01-07
    • 2023-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多