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

上一篇是 介绍装饰器、继承、元类、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只能普通的代码理解,但整段的代码运行结果他理解不了。然后看代码时候苦难一点。

第五种方式,python使用组合来添加类方法和属性(二),以selenium的webdriver为例的更多相关文章

  1. Python字符串拼接的五种方式

    第一种 通过加号(+)的形式 print('第一种方式通过加号形式连接 :' + 'love'+'Python' + '\n') 第二种 通过逗号(,)的形式 print('第二种方式通过逗号形式连接 ...

  2. 五种方式让你在java中读取properties文件内容不再是难题

    一.背景 最近,在项目开发的过程中,遇到需要在properties文件中定义一些自定义的变量,以供java程序动态的读取,修改变量,不再需要修改代码的问题.就借此机会把Spring+SpringMVC ...

  3. Android_安卓为按钮控件绑定事件的五种方式

    一.写在最前面 本次,来介绍一下安卓中为控件--Button绑定事件的五种方式. 二.具体的实现 第一种:直接绑定在Button控件上: 步骤1.在Button控件上设置android:onClick ...

  4. javaScript中定义类或对象的五种方式

    第一种方式: 工厂方法 能创建并返回特定类型的对象的工厂函数(factory function). function createCar(sColor){ var oTempCar = new Obj ...

  5. Spring事务配置的五种方式(转载)

    Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分. DataSo ...

  6. Spring事务配置的五种方式

    Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分. DataSo ...

  7. Android数据存储五种方式总结

    本文介绍Android平台进行数据存储的五大方式,分别如下: 1 使用SharedPreferences存储数据     2 文件存储数据       3 SQLite数据库存储数据 4 使用Cont ...

  8. Mysql查看版本号的五种方式介绍

    Mysql查看版本号的五种方式介绍 作者: 字体:[增加 减小] 类型:转载 时间:2013-05-03   一.使用命令行模式进入mysql会看到最开始的提示符;二.命令行中使用status可以看到 ...

  9. Spring事务配置的五种方式 -- 越往后需要Spring版本越高

    第五种 基本零配置  个人感觉第四种也可以 Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三部分,无论哪种配置方式, ...

随机推荐

  1. AR2220 通过cpu-defend policy处理大量大量arp广播的小技巧

    今天发现有局域网里面有几台电脑中毒了,在大量的发送ARP报文,导致设备cpu利用率很高. 一.查看display cpu-defend statistics 发现arp-reply  arp-requ ...

  2. 大型机、小型机、x86服务器的区别

    原文:http://servers.pconline.com.cn/gc/1202/2679853_1.html 大型机.小型机.x86服务器的区别 首先来讲x86服务器,与平常人们所接触的台式机笔记 ...

  3. Extjs4.x TreeGrid Dirty 更新数据,dirty标记不会自动清除的bug

    如上图所示,当修改某个属性值,成功提交后,dirty的小三角不会自动清除,这个是官方treegrid的一个bug,目前尚未解决. bug:http://www.sencha.com/forum/sho ...

  4. MSSQL跨服务器查询

    1.因为此功能服务器安全配置的一部分而被关闭,所以我们先开启 reconfigure reconfigure 2.如果需要关闭,执行 reconfigure reconfigure 3.查询语句 SE ...

  5. Redis管道传输

    Redis是一个TCP服务器,并支持请求/响应协议.redis的一个请求完成需要下面的步骤: 客户端发送一个查询到服务器,并从套接字中读取,通常在封闭的方式,对服务器的响应. 服务器处理命令并将响应返 ...

  6. js关于函数和对象的概念

    <script type="text/javascript"> function func1(fn){ if(typeof(fn)=="function&qu ...

  7. svn出现skips remain conficted,不能更新代码问题

    出现: skips remain conficted One or more files are in a conflicted state 然后commit的时候出现,很多都已经deleted,但是 ...

  8. 9、Qt 事件处理机制

    原文地址:http://mobile.51cto.com/symbian-272812.htm 在Qt中,事件被封装成一个个对象,所有的事件均继承自抽象类QEvent. 接下来依次谈谈Qt中有谁来产生 ...

  9. RIP路由协议及工作原理

    RIP路由协议及工作原理 RIP(Routing information Protocol,路由信息协议)是应用较早.使用较普遍的内部网关协议(Interior Gateway Protocol,IG ...

  10. linux下查看目录下某种文件类型累计的代码行数

    find 路径 -name '*.py' | xargs wc -l