python类 函数 变量

面向对象三大特性:封装 继承 多态
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.类


class类 object类 type类的关系

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。