getattr() 函数用于返回一个对象属性值
def getattr(object, name, default=None): # known special case of getattr
"""
getattr(object, name[, default]) -> value
Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
When a default argument is given, it is returned when the attribute doesn't
exist; without it, an exception is raised in that case.
"""
pass
class A:
bar = 1
a = A()
# 方式1:通过类对象获取属性bar值
print(a.bar)
# 方式2: 通过getattr方法获取属性bar值
value = getattr(a, 'bar')
print(value)
运行结果:
1
1
# 属性bar2不存在,为类A增加一个bar2属性,且值为3
d = getattr(a, 'bar2', 3)
print(d)
运行结果:
3
# 属性bar3不存在, 没有默认值,触发异常
e = getattr(a, 'bar3')
print(e)
运行结果:
Traceback (most recent call last):
File "E:\Coding\python-workspace\base_tec\my_getattr.py", line 34, in
e = getattr(a, 'bar3')
AttributeError: 'A' object has no attribute 'bar3'. Did you mean: 'bar'?
class B:
def set(self, c, d):
print(c + d)
b = B()
res1 = getattr(b, 'set')(c=1, d=2)
res2 = getattr(B(), 'set')(c=2, d=3)
data = {
"c": 5,
"d": 6
}
# 反射加解包,将参数值存储在字典中。此方式可以用于发送接口请求,将请求数据存储在一个字典中,调用post/get请求方法,效果等同于requests.get()、requests.post()
res3 = getattr(B(), 'set')(**data)
运行结果:
3
5
11
将字符串str当做有效的表达式来求值并返回计算结果
a = '1+1'
print(eval(a)) # 2
a = '[[1,2],[3,4],[5,6]]'
b = eval(a)
print(b)
print(type(b))
运行结果:
[[1, 2], [3, 4], [5, 6]]
<class 'list'>
示例1:
a = '[1,2],[3,4],[5,6]'
b = eval(a)
print(b)
print(type(b))
运行结果:
([1, 2], [3, 4], [5, 6])
<class 'tuple'>
示例2:
a = '1,2,3,4,5,6'
b = eval(a)
print(b)
print(type(b))
运行结果:
(1, 2, 3, 4, 5, 6)
<class 'tuple'>
a = "{'a': 1,'b': 2}"
b = eval(a)
print(b)
print(type(b))
运行结果:
{'a': 1, 'b': 2}
<class 'dict'>
result = eval("'+' * 5")
print(result)
运行结果:
+++++
input_number = input("请输入一个加减乘除运算公式:")
print(eval(input_number))
运行结果:
请输入一个加减乘除运算公式:1+5
6
因为在input时,用户直接通过os这个模块来调用system方法可以执行任何的终端命令,所以eval滥用于input会有安全隐患。
__import__('os').system('ls')
# 等价代码(上面代码等价于下面代码)
import os
os.system('终端命令')
import json
import logging
import allure
import jsonpath
import requests
# 工具类/关键字驱动类/基类
class ApiKey:
# get请求的封装:因为params可能存在无值的情况,存放默认None
@allure.step("发送get请求")
def get(self, url, params=None, **kwargs):
return requests.get(url=url, params=params, **kwargs)
@allure.step("发送post请求")
# post请求的封装:data也可能存在无值得情况,存放默认None
def post(self, url, data=None, **kwargs):
return requests.post(url=url, data=data, **kwargs)
@allure.step("获取返回结果字典值")
# 基于jsonpath获取数据的关键字:用于提取所需要的内容
def get_text(self, data, key):
# jsonpath获取数据的表达式:成功则返回list,失败则返回false
# loads是将json格式的内容转换为字典的格式
# jsonpath接收的是dict类型的数据
dict_data = json.loads(data)
value = jsonpath.jsonpath(dict_data, key)
if isinstance(value, list):
return value[0]
else:
return value
@allure.step("断言实际结果等于预期结果")
def my_assert(self, acutal, expect):
try:
assert acutal == expect
except:
return "断言失败"
else:
return "断言成功"
ak = ApiKey()
# 为了简化例子步骤,将接口测试用例写成如下格式。实际上dict_data是从excel表格中读取到的测试用例。从excel对出来的都是字符串,因此使用eval方法将字符串转换成其他有效的数据类型。
dict_data = {
'url': "http://shop-xo.hctestedu.com/index.php?s=api/user/login",
'params': eval('{"application": "app",\n"application_client_type": "weixin"}'),
'headers': eval('None'),
'data': eval('{"accounts":"zzss","pwd":"123456","type": "username"}')
}
# 发起请求
# 反射+解包,等同于 requests.post()
res = getattr(ak, 'post')(**dict_data)
# 打印响应报文
print(res.text)
运行结果:
{"msg":"登录成功","code":0,"data":{"id":"70734","username":"zzss","nickname":"","mobile":"","email":"","avatar":"http:\/\/shop-xo.hctestedu.com\/static\/index\/default\/images\/default-user-avatar.jpg","alipay_openid":"","weixin_openid":"","weixin_unionid":"","weixin_web_openid":"","baidu_openid":"","toutiao_openid":"","qq_openid":"","qq_unionid":"","integral":"189","locking_integral":"0","referrer":"0","add_time":"1646195490","add_time_text":"2022-03-02 12:31:30","mobile_security":"","email_security":"","user_name_view":"zz","is_mandatory_bind_mobile":0,"token":"f3e24ef665bad26785704838ccxba794"}}