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__)