面向对象三大特性:封装 继承 多态
https://ceshiren.com/t/topic/24692
python是一门面向对象的语音,一切皆为对象!
对象由三部分组成:
https://blog.csdn.net/weixin_42639395/article/details/131544960
(1) 对象的标识(id)
标识对象的唯一性,对象的内存地址(对象一旦建立,id不会变化)
使用id()函数查看
(2) 对象的类型(type)
标识对象所属的类型
通过type()函数查看对象类型
(3) 对象的值(value)
值就是对象存储的具体数据(有些对象的值可变,有的不可变)
面向对象编程 https://ceshiren.com/t/topic/25968
1.类
1.1继承
子类(派生类 DerivedClassName)会继承父类(基类 BaseClassName)的属性和方法。
多继承
python可以多层继承
说明:需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在子类中未找到时,从左到右查找父类中是否包含方法。
login_page.py
class LoginPage:
def __init__(self,username,pwd):
self.username = username
self.pwd = pwd
# 初始化selenium driver
self.driver = webdriver.Chrome()
# todo: 隐士等待可能后续会和显示等待冲突
self.driver.implicitly_wait(3)
self.driver.get('url')
self.login()
def login(self):
pass
fc_firstPage.py
类FcfirstPage继承类LoginPage,由于没有重写初始化方法,可以直接继承父类方法
class FcfirstPage(LoginPage):
# 非车快速查询
def quickly_search(self,cust_id=None,phone_no=None):
pass
# 自己选择点击客户ID进入还是客户姓名
def entryCustinfo(self, cust_id=True):
pass
fcDifficultTask.py
类FcDifficultTask继承了类FcfirstPage,但是重写了初始化方法,那么就不能继承爷爷类的driver属性,会报错:FcDifficultTask没有driver属性
class FcDifficultTask(FcfirstPage):
def __init__(self,username,pwd):
self.fc_page = FcfirstPage(username,pwd)
self.driver = self.fc_page.driver
def fc_difficultTask(self):
self.quickly_search('1000452573063')
self.entryCustinfo()
# 报错,FcDifficultTask没有driver属性
self.driver.find_element(By.XPATH,"xx']").click()
self.driver.find_element(By.XPATH,"xx").click()
解决办法
使用super().init()方法,既可以把父类初始化的参数传递进入,下边的方法又能通过self直接引用driver属性(即为继承了爷爷类的属性)
fcDifficultTask.py
class FcDifficultTask(FcfirstPage):
def __init__(self,username,pwd):
super().__init__(username,pwd)
1.2其他重要概念
self :代表类的实例(非类)
1.3object类
所有类的父类,因此所有类都有object类的属性和方法
object类相关的方法:
- 内置函数dir():查看指定对象的属性
- str()方法:返回一个对对象的描述(常用于print()方法,帮助我们查看信息,经常对这个方法重写)
class Student(object):
def __init__(self,name,age):
self.name = name
self.age = age
# 方法重写
def __str__(self):
return '名字是{},年龄是{}'.format(self.name,self.age)
if __name__ == '__main__':
stu = Student('lucky',18)
print(dir(stu))
# print(stu,type(stu))
print(stu)
print(type(stu))
# 输出1
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduc
e_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'name']
# 输出2
名字是lucky,年龄是18
# 输出3
<class '__main__.Student'>
2.函数/方法
2.1类的方法
在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数,self 代表的是类的实例。
分类:
https://www.cnblogs.com/nbk-zyc/p/13213122.html
(1)实例方法
- 第一个参数是实例本身,使用【self】表示
- 实例方法中,通过【self】操作实例属性,【类名】来操作类属性
- 实例方法只能通过实例对象调用
(2)类方法
类方法和静态方法使用场景和区别
- 使用【classmethod】修饰函数,第一个参数是类本身,用【cls】表示
- 类方法中,使用【cls】来操作类属性,不能操作实例属性
- 类方法可通过实例对象或者类对象调用
class Student(object):
COUNT = 1
def __init__(self,name,age):
self.name = name
self.age = age
@classmethod
def class_fun(cls):
cls.COUNT = 5
return cls.COUNT
if __name__ == '__main__':
stu = Student('lucky',18)
print(stu.COUNT) # 1
print(stu.class_fun()) # 5
(3)静态方法
- 使用【staticmethod】修饰函数,不需要任何参数(和普通函数一样,只是放到类中实现而已)
- 只能通过【类名】操作类属性,参考类方法的后两条
class Student(object):
COUNT = 1
def __init__(self,name,age):
self.name = name
self.age = age
# Student.COUNT=2
@staticmethod
def static_fun(value):
Student.COUNT =5
print(f'测试数量{Student.COUNT + value}')
if __name__ == '__main__':
Student.static_fun(2) # 7
(4)属性方法
属性访问器(Getter)和修改器(Setter)用来访问和修改属性的特殊方法。
访问器:使用【property】修饰函数,self作为第一个参数
修改器:使用【访问器名.property】修饰,self作为第一个参数
可以引用类的变量和实例变量
class Student(object):
COUNT = 1
def __init__(self,name,age,radius):
self.name = name
self.age = age
self._radius = radius #私有属性
# 属性访问器(Getter)
@property
def radius(self):
return self._radius
@radius.setter
def radius(self,value):
if value>0:
self._radius = value
else:
raise ValueError('此数字不正确')
类的私有方法
__private_method:两个下划线开头,声明该方法为私有方法,只能在类的内部调用 ,不能在类的外部调用。
self.__private_method
类的专有方法
即为object类的方法(因为所有类都继承于object类) https://blog.csdn.net/weixin_43201090/article/details/110502101
https://www.cnblogs.com/sunbines/p/17450311.html
# 有如下这些方法,下方举例说明几个
dir() # 返回对象所有属性
__str__() #返回对象描述
__len__() #相当于len(),对没有len()的对象重新__len__()
__add__() # 实现两个对象加法计算
2.2函数
匿名函数 lambda
https://www.cnblogs.com/mrwhite2020/p/16500321.html
省去定义函数的过程,精简代码
语法:lambda 形式参数 : 函数表达式
用途:是作为其他函数的参数,例如map()、filter()、reduce()等高阶函数
例子:
# 与if else结合
num_is_up3 = lambda x: 'up' if x>=3 else 'down'
print(num_is_up3(3)) #up
print(num_is_up3(1)) # down
# 与map函数结合
list1 = [1, 2, 3, 4, 5]
list2 = map(lambda x: x**2, list1)
print(list(list2)) #[1,4,9,16,25]
3.类属性/变量
三种属性/变量
(1)类变量/属性
定义在类中,但是定义在类方法外的变量。——类变量在整个实例化的对象中是公用的(共享)。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
- 访问:可以通过类/类实例访问到—— 对象.属性名
- 修改:类外只能通过【类对象】(实例名.变量名)来修改(类内可以self.变量名或者classname.变量名引用修改),无法通过类实例属性修改
class Student(object):
COUNT = 1
def __init__(self,name,age):
self.name = name
self.age = age
self.COUNT=2 #也可以 Student.COUNT=2
# 方法重写
def __str__(self):
return '名字是{},年龄是{},数量{}'.format(self.name,self.age,self.COUNT)
if __name__ == '__main__':
stu = Student('lucky',18)
print(stu)
stu.COUNT=3
print(stu.COUNT)
(2)实例变量/属性
任意类方法内部,以self.变量名的定义方式定义的【在__init__()方法定义的】。——类方法内共享,self.xx 只能通过对象名访问,不能类名访问
- 只能通过【实例对象】来访问和修改(对象.属性名),类对象无法访问修改
(3)局部变量
类的方法内,以变量名=变量值 的方式定义——仅在方法内使用
类的私有属性
__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时
self.__private_attrs。