zoukankan      html  css  js  c++  java
  • 第五种方式,python使用组合来添加类方法和属性(二),以selenium的webdriver为例

    组合优点多,但经常比继承需要额外的代码。

     上一篇是 介绍装饰器、继承、元类、mixin,四种給类动态添加类属性和方法的四种方式。

    此篇介绍直接把被组合的类的属性直接加入到类里面,前面的四个例子很简单,这次来个实际例子的举例。

    # coding:utf-8
    
    import logging
    import unittest
    from selenium import webdriver
    
    
    class DriverWrapper():
        def __init__(self):
            self.driver = webdriver.Chrome()
            self.logger = logging.getLogger(self.__class__.__name__)
            self.logger.setLevel(logging.DEBUG)
            stream_handler = logging.StreamHandler()
            stream_handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(filename)s - %(lineno)d - %(levelname)s - %(message)s', "%Y-%m-%d %H:%M:%S"))
            self.logger.addHandler(stream_handler)
    
        def open(self, url):
            self.driver.get(url)
    
        def find_element_by_css_selector(self, css_str):    # 使用自定义的方法覆盖了原方法,比如先打印出一段话
            self.logger.debug('要查找的元素的css选择器是 --> ' + css_str)
            self.driver.find_element_by_css_selector(css_str)
    
        def __getattr__(self, item):                #想把其他的webdriver的操作方法直接添加进来,不一个一个的再写一个方法然后调用driver属性的方法,不想一直搞冗余的代码,可以这么做。python先使用__getattribute__,查不到才会调用__getsttr__方法,利用这个特性,来实现这个添加driver的属性到自己类里面
            return getattr(self.driver, item)
    
    
    class _Test(unittest.TestCase):
        def test(self):
            driver_wrapper = DriverWrapper()
            driver_wrapper.open('https://www.baidu.com')         # 有人不喜欢用get,可以叫open什么的
            driver_wrapper.find_element_by_css_selector('#kw')   # 当类中存在方法,使用了自己类里面的方法,所以每次使用css选择器查找元素时候会打印一个日志
            driver_wrapper.find_element_by_id('kw')              # 当类中不存在此方法,使用Chrome类的方法

    driver_warpper.driver.close() # 这样做也可以,但不算是动态添加属性了,这是直接使用的该实例的driver属性的方法,driver属性是Chrome的一个实例。
    if __name__ == '__main__': unittest.main()

    1、这样就是组合来动态添加方法和属性了,DriverWrapper类的实例可以直接使用一切Chrome类的实例的方法和属性。

    2、如果不重写__getattr__方法,那么driver_wrapper.find_element_by_id('kw')  这么做就会报错,因为DriverWrapper类没有定义过这个方法。

    一共五种方法动态扩展。

    但元类 装饰器 和此篇的组合然后重写__getattr__来添加方法和属性,有个重大弊端是,因为太动态了,pycharm写代码时候,不能自动补全这些被扩展添加的方法和属性,这个是硬伤,因为pycahrm只能普通的代码理解,但整段的代码运行结果他理解不了。然后看代码时候苦难一点。

     

  • 相关阅读:
    Asp.net 主题 【2】
    Asp.net 主题 【1】
    登陆验证码
    Ajax进阶
    Ajax
    Django之权限管理
    Django之Form进阶
    Django之知识总结
    Django之form表单认证
    Django之ORM查询复习与cookie
  • 原文地址:https://www.cnblogs.com/ydf0509/p/9213793.html
Copyright © 2011-2022 走看看