美文网首页
Python中的reflect反射机制

Python中的reflect反射机制

作者: 猫与测试 | 来源:发表于2019-11-20 01:16 被阅读0次

什么是反射?

这里我先说结论:

Python 中的反射其实就是使用字符串调用函数或者方法。

这对于我们设计一些自动化测试框架,特别是类似关键字驱动的时候非常有用。

什么叫用字符串来调用函数或者方法呢?

想想这样一个场景,我通过 excel、数据库或者其他方式记录了自动化测试的操作步骤。其中的一列是对应一段 Python 函数或者方法,另外的列是给这个函数或者方法的参数。

这样有什么好处呢,这样就不用对每一句的测试步骤都去单独编码。

简单示例

我们先以一个非常简单的和测试无关的案例来介绍一下反射的使用。

完成这个案例需要如下几个内容:

  1. 先有一个 calc.py 文件中编写了几个数学运算函数
  2. 建立一个 step.yaml 文件,在文件中每行列出要操作的函数和函数的参数
  3. 最后在 demo.py 文件中定义一段代码,从 step.yaml 数据中读取数据,然后执行对应的代码

通过在 yaml 文件中不断添加数据行,就可以驱动代码执行不同的函数。这很像数据驱动或者关键字驱动的思想。

请务必按照这些代码编写一次,然后观察运行结果,很容易就明白什么意思。如果你偷懒不想去写,只想通过看来搞懂,那请自求多福

calc.py

def add(*n):
    '''累加'''
    return sum(n)

def sub(a, b):
    '''减法'''
    return a - b

def power(a, b):
    '''乘方'''
    return a ** b

def mult(*n):
    '''累乘'''
    r = 1
    for i in n:
        r *= i
    return r

def division(a, b):
    '''除法'''
    return a / b

然后在 step.yaml 文件中定义要操作的函数和数据。

如果对 Yaml 不熟悉, 请参看《YAML 文件介绍》

step.yaml

- method: add
  args: [1,2,3,4,5,6]
- method: power
  args: [6,7]
- method: sub
  args: [8,11]
- method: mult
  args: [3,4,5]
- method: division
  args: [6,3]

在 yaml 中定义了两个字段:method 用来标识需要调用的函数名 ,args 用来标识函数需要的参数。

接下来在 demo.py 中编写读取 yaml 的代码,并将读取出来的方法和参数通过反射的方式调用 calc.py 中的函数。

import calc  # 引入calc.py
import yaml  # 引入yaml处理库

with open('step.yml') as f:
    data = yaml.load(f, Loader=yaml.SafeLoader)  # 读取yaml中的数据
    for step in data:
        fun = getattr(calc, step['method'])  # 使用反射中的getattr访问calc模块中函数
        print(fun(*step['args'])) # 执行函数 

这里最关键的是这两句代码:

fun = getattr(calc, step['method'])  # 使用反射中的getattr访问calc模块中函数
fun(*step['args']) # 执行函数 
  • getattr(object, name) :从对象 oject 中调用 name 属性。因为在 Python 中一切都是对象,所以任何地方都可以用反射函数。这里是从文件(模块)calc.py 中调用其中的函数,函数名是我们从 yaml 文件中读取出来的字符串;
  • fun(*step['args']):这一句是将参数传给函数,因为 calc.py 中的参数个数是不一样的,所以这里统一读取 yaml 中的 args 字段。

不知你有没有一定明白?就是把字符串(yaml 中的 method 字段)反射到 Python 对象的属性中。

当然这个例子稍微有点歧义的是写的函数都放在一个文件中而不是一个类中,这主要为了方便理解。写在类里面是一样的,只是 getattr() 的第一个参数要写成实例对象。

# 省略类定义的过程
calc = Calc()
getattr(calc, 'add')

反射函数

除了上面的 getattr() 函数外,还有三个函数也是用于反射:

  • hasattr(object, name):判断某个对象是否存在 name 属性,name 为字符串
  • delattr(object, name):删除某个对象的 name 属性
  • setattr(object, name, value):为某个对象设置 name 属性,并通过 value 为属性指定值(值可以是任意数据类型或者函数等)

相关文章

  • ES6(十二)—— Reflect

    Reflect 反射,什么是反射机制? Reflect简介 为什么要用Reflect? Reflect API.a...

  • Python中的reflect反射机制

    什么是反射? 这里我先说结论: Python 中的反射其实就是使用字符串调用函数或者方法。 这对于我们设计一些自动...

  • reflect使用

    reflect概述 反射是一种检查存储在 接口变量中的<值,类型>对 的机制,借助go反射包提供的reflect....

  • 33-reflect反射

    reflect反射 对编程语言比较熟悉的同学,应该听说过“反射”这个机制。Python作为一门动态语言,当然不会缺...

  • 反射机制(reflect)

    一.反射机制用来描述所有的类Class 用来类描述类本身Package 用来描述类所属的包Field 用来描述类的...

  • Java Reflect(反射)机制详解

    Java Reflect(反射)机制详解 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法...

  • Java基础之反射

    Java-Reflect Class类的使用 方法的反射 成员变量的反射 构造函数的反射 Java类加载机制 一、...

  • [JAVA学习笔记] 反射机制

    [JAVA学习笔记] 反射机制 Java的反射通过Class类和java.lang.reflect类库实现。通过它...

  • Java Reflect 反射机制

    Java Reflect 反射机制 类字节码文件是在硬盘上存储的,是一个个的.class文件。我们在new一个对象...

  • Reflect in PHP(PHP中的反射机制)

    原文链接 by Patkos Csaba18 Apr 2013反射通常被定义为一个程序在执行的时候自我检查和修改自...

网友评论

      本文标题:Python中的reflect反射机制

      本文链接:https://www.haomeiwen.com/subject/dpbvictx.html