python+selenium4(WEB UI自动化测试)+Page_object(代码设计思维)+unittest(单元测试框架)+ddt(数据驱动)+beautifulreport(自动生成测试报告)
函数是一等公民
在Python中,函数是"一等公民",意味着函数可以:
赋值给变量
作为参数传递给其他函数
作为其他函数的返回值
匿名函数(Lambda函数)(由于没有名字, 所有不能被反复调用)
当需要一个简单的函数,又不想正式定义一个函数时,可以使用lambda表达式:
#常规函数
def square(x):
return x ** 2
#等价的lambda函数
square_lambda = lambda x: x ** 2
print(square(5)) #输出:25
print(square_lambda(5)) #输出: 25
按值从小到大排序,返回排序后的键值对列表
#sorted()里面有一个Key参数,是指按照xxxxx进行排序。
[(a, 4), (b,8),(c,1)]
sorted_items = sorted(my_dict.items(), key=lambda x: x[1]) # 取元组项的下标为1的值
按照姓名长度排序
#按照姓名长度排序
names = ["张三","李四","王小明","赵云"]
names.sort(key=lambda name: len(name))
print(names) #输出:['张三,'李四,'赵云','王小明
过滤列表中的偶数
numbers = [1, 2, 3, 4, 5,6, 7,8, 9, 10]
even_numbers = list(filter(lambda x: x%2 ==0, numbers))
print(even_numbers) #输出: [2,4,6, 8, 10]
python面向对象
核心概念:
类: 抽象出来给世界万物的归类. 拥有共同的属性和方法.
对象: 类的实例化就叫对象 实际造出来的产物.
属性: 特征
方法: 就是指动作, 在类里面称之为方法
封装: 代码行被类或者函数封装起来, 不需要关注具体如何实现的, 只需要其有什么作用即可
继承: 父类的属性和方法, 子类均可以进行继承
多态: 父类和子类有同一个方法, 但是表现形式可以不一样, (同一种事物的不同的表现形式)
声明这是一个类:
class 类名(Object): #继承Object,可以省略:
'''
这是类的文档注释
'''
class 类名(): 在python3中, Object是所有类的父类 基类
class 类名: 这三种都正确
类的创建示例
class ChineseDog(object):
'''
这是一个狗类
'''
country='china' # 雷属性属性
def __init__(self, name, age, variety)
'''
:param name: 名字
:param age: 年龄
:param variety: 品种
'''
self.name = name
self.age = age
self.variety = variety
类的创建示例
class ChineseDog(object):
''' 这是一个狗类
''' country='china' # 雷属性属性
# __init__() 这是python的构造函数
# self 指向实例本身, 指的是当前的实例对象
def __init__(self, name, age, variety):
''' :param name: 名字
:param age: 年龄
:param variety: 品种
''' self.name = name
self.age = age
self.variety = variety
def dog_speak(self): # 在类里面叫方法 在类外面叫在函数
print('%s: 汪汪汪' % self.name)
# 创建一条狗
# 当创建一个狗类的实例对象时,会调用__init__()函数
# 将实例属性绑定到创建的实例化对象dog1上
dog1 = ChineseDog('旺财', 3, '土狗')
写一个类实例
# people
class People(object):
def __init__(self, name, age):
self.name = name
self.age = age
self.sex = sex
# 唱
def singing(self):
print('%s is singing' % self.name)
# 跳
def jumping(self):
print('can jumping')
# rap def rap(self):
print('can rap')
# 球
def ball(self):
print('can play ball')
caixukun = People('caixukun', 18, '男')
# 打印全部属性
print(caixukun.__dict__)
caixukun.rap()
class ChineseSinger:
def __init__(self, name, age, sex='男'): # 构造函数也可以初始化值
"""初始化歌手的基本属性
Args:
name: 歌手姓名
age: 歌手年龄
sex: 歌手性别,默认为'男'
""" self.name = name
self.age = age
# 验证性别输入是否有效
if sex not in ('男', '女'):
raise ValueError("性别必须是'男'或'女'")
self.sex = sex
def sing(self, year):
"""展示歌手的演唱技能
Args:
year: 练习时长描述
""" print(f"我叫{self.name},我练习时常{year}")
return self.name
# 创建类的实例
singer1 = ChineseSinger(name="蔡徐坤", age=29)
singer1.sing("2年半") # 调用实例方法
print(singer1.name) # 访问实例属性
类属性可以直接采用类名.类属性名 达到访问类属性的目的, 而实例属性则需要通过
实例对象.实例属性名 达到访问实例属性的目的。
self用来介绍这个类
__str__(self)
class People(object):
""" 初始化Person类的实例对象。
该构造函数接收三个参数:name、age和sex,并将它们分别赋值给实例变量。
这样做的目的是为了在创建Person对象时,能够将这些基本信息封装到对象中,
便于后续的操作和管理。
参数:
- name (str): 人物的姓名。
- age (int): 人物的年龄。
- sex (str): 人物的性别。
返回值:
无返回值,但会创建一个Person类的实例,并将name、age和sex赋值给实例变量。
""" def __init__(self, name, age,sex):
self.name = name
self.age = age
self.sex = sex
def __str__(self):
return '%s is %s years old, %s' % (self.name, self.age, self.sex)
# 唱
def singing(self):
print('%s is singing' % self.name)
# 跳
def jumping(self):
print('can jumping')
# rap def rap(self):
print('can rap')
# 球
def ball(self):
print('can play ball')
caixukun = People('caixukun', 18, '男')
# 打印全部属性
print(caixukun.__dict__)
caixukun.rap()
# 查看类文档
print(caixukun.__doc__)
# 直接打印对象
print(caixukun) # 会打印__str__()方法返回的结果
练习示例:
class Galley(object):
camp = 'demacia'
def __init__(self, name, life_value, attack_value, defense_value):
self.life_value = life_value
self.attack_value = attack_value
self.defense_value = defense_value
self.name = name
self.Equipment_column = []
# 致命打击 enemy: 敌人
def deadly_blow(self, enemy):
print(self.name+' is attacking '+enemy.name)
# 敌方的生命值应该=初始生命值-(我当前的攻击力减去敌方的防御)
enemy.life_value -= self.attack_value - enemy.defense_value
# 普通攻击
def attack(self, enemy):
print(self.name + ' is attacking ' + enemy.name)
# 敌方的生命值应该=初始生命值-(我当前的攻击力减去敌方的防御)
enemy.life_value -= self.attack_value - enemy.defense_value
# 创建一个锐雯类
class Riven(object):
camp = 'Noxus' def __init__(self, name, life_value, attack_value, defense_value):
self.life_value = life_value
self.attack_value = attack_value
self.defense_value = defense_value
self.name = name
self.Equipment_column = []
# 普通攻击
def attack(self, enemy):
# 敌方的生命值应该=初始生命值-(我当前的攻击力减去敌方的防御)
enemy.life_value -= self.attack_value - enemy.defense_value
# 示例花一个盖伦, 去攻击锐雯
Galley1 = Galley('潇湘观雨晴', 1000, 100, 100)
Riven1 = Riven('黑白', 1000, 200, 50)
Galley1.attack(Riven1)
print(Riven1.life_value)
Riven1.attack(Galley1)
print(Galley1.life_value)
游戏攻击逻辑与装备加长
class Gay():
camp='demacia' def __init__(self,name,life_value,Defense_value,attck_value):
self.name=name #姓名
self.life_value=life_value #生命值
self.Defense_value=Defense_value #防御力
self.attck_value=attck_value #攻击力
self.Equipment_column=[] #装备栏
def normal_attack(self,enemy):
#普通攻击
print("我开始攻击了")
#敌方的生命值应该=初始生命值-(我当前的攻击力减去敌方的防御)
enemy.life_value=enemy.life_value-(self.attck_value-enemy.Defense_value)
def insert_Equipment(self,Equipment):
''' 穿上装备
:param Equipment_name: 这是装备的名称
:return: None
''' print(f"恭喜你,你购买了一把{Equipment.name}")
if len(self.Equipment_column)<6:
#计算装备栏是否大于6
self.Equipment_column.append(Equipment.name) #给装备栏添加一个装备的名字
#穿上装备之后生命值的变化
self.life_value+=Equipment.life_value
#穿上装备之后防御力的变化
self.Defense_value+=Equipment.Defense_value
#穿上装备之后攻击力的变化
self.attck_value+=Equipment.attck_value
else: print("您没有多余装备栏")
def deadly_blow(self,enemy):
#致命打击要攻击的对象
print("对敌造成1.5倍伤害")
#伤害值计算方式/
Damage_Value=self.attck_value*1.5-enemy.Defense_value
#计算敌方剩余的生命值
enemy.life_value-=Damage_Value
class RiWen():
camp="Noxus" def __init__(self,name,life_value,Defense_value,attck_value):
self.name=name #姓名
self.life_value=life_value #生命值
self.Defense_value=Defense_value #防御力
self.attck_value=attck_value #攻击力
self.Equipment_column=[] #装备栏
class Equipment():
#装备类
def __init__(self,name,life_value,Defense_value,attck_value):
self.name=name
self.life_value=life_value
self.Defense_value=Defense_value
self.attck_value=attck_value
Gay1=Gay("潇湘观雨晴",800,56,65)
RiWen1=RiWen("黑白",750,50,72)
Equipment1=Equipment("无尽之刃",life_value=0,Defense_value=0,attck_value=100)
Gay1.insert_Equipment(Equipment1)
Gay1.deadly_blow(RiWen1)
print(Gay1.attck_value)
print(RiWen1.life_value)
扑克牌练习
class Poker :
def __init__(self,colour ,num):
self.colour = colour
self.num = num
def __str__(self):
return "{},{}".format(self.colour,self.num)
p1 = Poker("红桃","A")
p2 = Poker("黑桃","k")
#定义一个手的类
class Hand :
def __init__(self,poker):
self.poker = poker
left_hand = Hand(p1)
right_hand = Hand(p2)
print(right_hand.poker.colour)
#定义一个人的类
class Person :
def __init__(self,left_hand ,right_hand):
self.left_hand = left_hand
self.right_hand = right_hand
def show_hand(self):
print(self.right_hand.poker,self.left_hand.poker)
def exchange(self):
self.left_hand.poker ,self.right_hand.poker =self.right_hand.poker ,self.left_hand.poker
person1=Person(left_hand,right_hand)
person1.show_hand()
person1.exchange()
person1.show_hand()
私有属性和私有方法
class Women:
sex = '女'
def __init__(self, name, age):
self.name = name
# 私有(在实例属性前面加上两个,代表 # 这是私有属性, 私有属性无法直接诶访问)
self.__age = age
# 私有
def __str__(self):
return 'name:' + self.name
# 提供访问私有属性的方法(常用的一种方式)
def _get_age(self):
return self.__age
def __makeup(self):
print("见男朋友,我得化妆")
Wo1 = Women('小红', 18)
print(Wo1)
# 访问私有属性的方式有两种
# 使用_类名__属性名强行访问.
print(Wo1._Women__age) # 尽可能不采用此种方式
# 使用get访问私有属性 格式化输出
print('name:', Wo1.name, 'age:', Wo1.get_age())
#强制性调用私有方法
women1._Women__makeup
(一)数据保护
私有属性可以保护数据的完整性和安全性。比如,在一个用户类中,用户的密码肯
定是不希望被外部随意获取和修改的,所以可以将密码属性设置为私有属性。这样,外
部代码就不能直接访问和修改密码,只能通过类提供的特定方法来进行操作,比如登录
验证时的密码比对方法。
(二)封装性(封装性的体现, 数据保护,私有方法)
私有属性和方法有助于实现类的封装性。封装是面向对象编程
的一个重要特性,它把类的内部实现细节隐藏起来,只对外提供一
些必要的接口(公共方法)。通过私有属性和方法,我们可以将类
的一些内部状态和实现逻辑封装起来,使得类的使用者只需要关注
类提供的公共功能,而不需要了解类的内部具体实现,这样可以降
低代码的复杂性,提高代码的可维护性
静态方法 @staticmethod (独立于对象也独立于类, 没有形参)
静态方法既不需要传递类对象,也不需要传递实例对象(没有形参)。静态
方法可以独立于类的任何实例或类级别而存在,因此它们是最为模块化、灵
活和可维护的方法类型之一。
静态方法不能访问类的变量。
静态方法不需要特殊的参数,但仍然可以使用默认参数。
静态方法往往更容易维护和测试,因为它们不会改变且不依赖于类的状态。
由于静态方法可以独立于类而存在,它们也可以很方便地跨越模块、包和
应用程序。
# 类的装饰器
class Person:
def __init__(self):
print("我是一个一个人")
@classmethod # 类方法, 装饰器, 通过装饰器添加类方法
def speak(cls):
print("发烧发生的发生的发丹参多酚酸")
# 类方法无法调用实例属性
Person.speak()
### 类方法示例
class MyClass(object):
x = 1 # 定义类属性
def __init__(self):
self.y = 2 # 定义实例属性
@classmethod
def func(cls):
print(f'类属性x为{cls.x}') # 可以调用类属性
# print(cls.y) # 这里会报错,无法访问实例属性
MyClass.func() # 调用类方法
class MyClass():
@staticmethod #特殊标识符(相当于直接写了一个函数放在类里面,独立于类存在)
def func(n): #定义一个静态方法
print(f"我是一个静态方法,属性n为: {n}") #调用属性 不需要关键字
MyClass.func(10) # 调用静态方法,传入一个参数
property:将方法变(伪装成)成属性
class Women:
def __init__(self, name, age):
self.name = name
self.__age = age # 私有属性
@property # 将方法转为属性调用
def tell_age(self):
return self.__age
women1 = Women(name="杨幂", age=30)
print(women1.tell_age) # 注意这里是属性调用,不需要()
@property的方法: getter、 setter和deleter
当使用@property装饰器时,可以定义三种方法来操作属性: getter、
setter 和 deleter。
Getter方法: getter方法用于获取属性的值。它的命名需要与@property
装饰器的名称相同。在类中定义了@property装饰器的方法就是getter方
法(默认方法)。
class Person:
def __init__(self):
print("我是一个一个人")
@classmethod # 类方法, 装饰器, 通过装饰器添加类方法
def speak(cls):
print("发烧发生的发生的发丹参多酚酸")
# 类方法无法调用实例属性
Person.speak()
### 类方法示例
class MyClass(object):
x = 1 # 定义类属性
def __init__(self):
self.y = 2 # 定义实例属性
@classmethod
def func(cls):
print(f'类属性x为{cls.x}') # 可以调用类属性
# print(cls.y) # 这里会报错,无法访问实例属性
MyClass.func() # 调用类方法
class MyClass():
@staticmethod #特殊标识符(相当于直接写了一个函数放在类里面,独立于类存在)
def func(n): #定义一个静态方法
print(f"我是一个静态方法,属性n为: {n}") #调用属性 不需要关键字
MyClass.func(10) # 调用静态方法,传入一个参数
# property:将方法变(伪装成)成属性
class Women:
def __init__(self, name, age):
self.name = name
self.__age = age # 私有属性
@property # 将方法转为属性调用
def tell_age(self):
return self.__age
# 修改age属性
@tell_age.setter # 需要采用property装饰的方法来作为前缀
def set_age(self, age):
self.__age = age
women1 = Women(name="杨幂", age=30)
print(women1.tell_age) # 注意这里是属性调用,不需要()
# #如果使用#property.setter修改属性。
women1.set_age = 18
print(women1.tell_age)
# 类的继承性
class Hero:
name = '英雄'
def __init__(self,name,life_value, Defense_value,attck_value):
self.name = name
self.life_value = life_value
self.Defense_value = Defense_value
self.attck_value = attck_value
def print(self):
print("英雄名称:%s,生命值:%d,防御力:%d,攻击力:%d" % (self.name, self.life_value, self.Defense_value, self.attck_value))
class Gay(Hero):
def __init__(self,name,life_value, Defense_value,attck_value,run):
# 指名道姓说明继承父类的构造函数
Hero.__init__(self,name,life_value, Defense_value,attck_value) self.run=run
# 盖伦类独有的属性 self.run = run
gay1 = Gay("si wang ru feng,chang ban wu shen", 500,45,65 ,3)
print(gay1.attck_value)
##类的继承
class zero():
def __init__(self,name,life_value,Defense_value,attck_value):
self.name=name
self.life_value=life_value
self.Defense_value=Defense_value
self.attck_value=attck_value
#单继承:
class Gay(zero):
def __init__(self,name,life_value,Defense_value,attck_value,run):
#指名道姓的继承父类的构造函数
zero.__init__(self,name,life_value,Defense_value,attck_value)
#超类继承方式。超类就是指父类。使用super()继承。目前就是为了防止
#显示继承。
def gayprint(self):
# 子类调用父类的方法
Hero.print(self)
super().print()
super(Gay,self).__init__(name,life_value,Defense_value,attck_value)
# 盖伦类独有的属性。
self.run=run
gay1=Gay("死亡如风",500,45,65,375)
print(gay1.run)
# python3中多继承遵循mro顺序。是一种菱形继承顺序或者称之为砖石继承
# 类名.__mro__ 看可以查看继承的类及顺序
print(Gay.__mro__)