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只能普通的代码理解,但整段的代码运行结果他理解不了。然后看代码时候苦难一点。

     

  • 相关阅读:
    241. Different Ways to Add Parentheses java solutions
    89. Gray Code java solutions
    367. Valid Perfect Square java solutions
    46. Permutations java solutions
    116. Populating Next Right Pointers in Each Node java solutions
    153. Find Minimum in Rotated Sorted Array java solutions
    判断两颗树是否相同
    求二叉树叶子节点的个数
    求二叉树第k层的结点个数
    将二叉排序树转换成排序的双向链表
  • 原文地址:https://www.cnblogs.com/ydf0509/p/9213793.html
Copyright © 2011-2022 走看看