文章目录
面向对象
对象初始对象
- 代码示例
# *_*coding:utf-8 *_*
# 设计一个类:类比生活中:设计一张登记表
class Student:
# 定义类成员属性
name = None
gender = None
nationality = None
native_place = None
age = None
# 创建一个对象:类比打印一张登记表
stu = Student()
# 对象属性进行赋值类比生活中填写表单
stu.name = "zsx"
stu.gender = "男"
stu.nationality = "China"
stu.native_place = "baoji"
stu.age = 18
# 获取对象中记录的信息
print(f'姓名:{stu.name},性别:{stu.gender},国籍:{stu.nationality},出生地:{stu.native_place},年龄:{stu.age}')
类的定义和使用
语法
类的定义
- class:关键字,表示要定义类
类的属性:类中的变量(成员变量)
类的行为:类中的函数(成员方法)
class 类名:
类的属性
类的行为
- 类的使用
对象=类名称()
成员方法的定义语法
self关键字是成员方法定义时,必须填写的
用来表示类对象自身,当我们使用类对象调用方法时,self会自动被Python传入
在方法内部,想要访问类成员变量,必须使用self
def 方法名(self,形参1, ... ,形参n)
方法体
代码示例
# *_*coding:utf-8 *_*
class Student:
# 成员属性
name = None
# 成员方法
def say_hi(self):
print(f'hi, {self.name}')
def say_hi1(self, msg):
print(f'hi, {self.name}, {msg}')
# 构建类对象
stu = Student()
# 给成员属性赋值
stu.name = "zs"
# 调用成员方法
stu.say_hi()
stu.say_hi1("你好")
内置方法
构造方法
python类可以使用:
__init__()
方法,称之为构造方法可以实现
在创建类对象的时候,会自动执行
在创建类对象的时候,会将传入参数自动传递给
__init__
方法使用
代码示例
# *_*coding:utf-8 *_*
class Student:
# 定义类成员属性
name = None
gender = None
age = 0
def __init__(self, name, gender, age):
self.name = name
self.gender = gender
self.age = age
stu = Student("zsx", "man", 18)
print(f'姓名:{stu.name}, 性别:{stu.gender}, 年龄:{stu.age}')
注意事项
不要忘记前后两个下划线
构造方法也是成员方法,不要忘记在参数列表中提供:self
在构造方法内定义成员变量,需要使用self关键字
字符串方法
问题:定义好类对象之后,如果直接打印类对象或者使用str强转打印,都会输出内存地址
通过
__str__
方法可以控制类转换为字符串的行为代码示例:在上面类中添加
__str__
方法
def __str__(self):
return f'姓名:{self.name}, 性别:{self.gender}, 年龄:{self.age}'
比较方法
__lt__
方法
小于符号比较方法
通过
__lt__
方法可以控制类中小于比较的行为代码示例
def __lt__(self, other):
return self.age < other.age
__le__
方法
小于等于符号比较方法
通过
__le__
方法可以控制类中小于等于比较的行为代码示例
def __le__(self, other):
return self.age <= other.age
__eq__
方法
- 等于符号比较方法
封装
- 将现实世界事务在类中描述为属性和方法,即为封装
私有成员
在类中描述属性和方法有时候是不公开使用的
定义私有成员的方法,在变量名或者方法名前面以
__
开头私有变量无法赋值,也无法使用
代码示例
# *_*coding:utf-8 *_*
class Phone:
# 私有变量
__curent_voltage = None # 当前电压
# 私有方法
def __keep_single_core(self):
print("cpu单核运行")
phone = Phone()
# 访问私有成员,不报错,但无效
# AttributeError: 'Phone' object has no attribute '__curent_voltage'
print(phone.__curent_voltage)
# 报错无法使用
# AttributeError: 'Phone' object has no attribute '__keep_single_core'
phone.__keep_single_core()
使用私有成员
私有成员无法被类对象使用,但是可以被其它成员使用
代码示例
# *_*coding:utf-8 *_*
class Phone:
# 私有变量
__curent_voltage = 0.5 # 当前电压
# 私有方法
def __keep_single_core(self):
print("cpu单核运行")
def call_by_5g(self):
if self.__curent_voltage >= 1:
print("5g通话已开启")
else:
self.__keep_single_core()
print("电量不足,无法使用5g通话")
phone = Phone()
phone.call_by_5g()
继承
定义:一个类继承另一个类的成员变量和成员方法
子类构建的类对象
有自己的成员变量和成员方法
可以使用父类的成员变量和成员方法
单继承
一个类继承自一个父类
语法
class 类名(父类名):
类内容
- 代码示例
# *_*coding:utf-8 *_*
class Phone:
IMEI = None # 序列号
producer = None # 厂商
def call_by_4g(self):
print("4g通话")
# 继承Phone类
class Phone2024(Phone):
face_id = True # 面部识别
def call_by_5g(self):
print("5g通话")
p2024 = Phone2024()
p2024.call_by_4g()
p2024.call_by_5g()
多继承
一个类可以继承多个父类
注意事项
- 多个父类中,如果有同名的成员,默认以从左到右为优先级
语法
class 类名(父类1,父类2, ... ):
类内容
- 代码示例
# *_*coding:utf-8 *_*
class Phone:
IMEI = None
producer = "HM2"
def call_by_5g(self):
print("5g通话")
class NFCReader:
nfc_type = "第5代"
producer = "HM1"
def read_card(self):
print('读取nfc卡')
def write_card(self):
print('写入nfc卡')
class RemoteControl:
rc_type = "红外遥控"
def control(self):
print("红外遥控开启")
class XiaoMePhone(Phone, NFCReader, RemoteControl):
# pass表示空,只做语法不全,没有实际含义
pass
my_phone = XiaoMePhone()
my_phone.call_by_5g()
my_phone.read_card()
my_phone.write_card()
my_phone.control()
# 多个类有同名属性时优先级为从左向右
print(my_phone.producer)
重写父类成员方法
子类对父类已有的方法进行重新定义
代码示例
# *_*coding:utf-8 *_*
class Phone:
def call_5g(self):
print("使用5g通话")
class MyPhone(Phone):
# 子类对父类的方法进行重写
def call_5g(self):
print("使用升级5g通话")
my_phone = MyPhone()
my_phone.call_5g()
调用父类同名成员
一旦重写了父类成员,那么类对象调用成员的时候,就会调用重写后的新成员
如果需要使用被复写的父类成员,需要特殊的调用
语法
# 方式一:使用父类名调用
使用成员变量:父类名.成员变量
使用成员方法:父类名.成员方法(self)
# 方式二:使用super()调用父类成员
使用成员变量:super().成员变量
使用成员方法:super().成员方法(self)
- 代码示例
# *_*coding:utf-8 *_*
class Phone:
id = 1
def call_5g(self):
print("使用5g通话")
class MyPhone(Phone):
id = 2
# 子类对父类的方法进行重写
def call_5g(self):
print("使用升级5g通话")
# 方式一:调用父类成员
print(f'父类id:{Phone.id}')
print(f'父类id:{Phone.call_5g(self)}')
# 方式二:调用父类成员
print(f'父类id:{super().id}')
print(f'父类id:{super().call_5g()}')
my_phone = MyPhone()
my_phone.call_5g()
类型注解
定义:在代码中涉及数据交互的地方,提供数据类型的注解(显式说明)
功能:
帮助第三方IDE工具对代码进行类型推断,协助做代码提示
帮助开发者自身对变量进行类型注解
支持
变量的类型注解
函数形参列表和返回值的类型注解
变量注解
对变量设置类型注解
语法:
变量:类型
代码示例
# *_*coding:utf-8 *_*
# 基础数据类型注解
var1: int = 10
var2: float = 3.12
var3: bool = True
var4: str = "sgfdghs"
class Student:
pass
# 类对象类型注解
stu: Student = Student()
# 基础容器类型注解
my_list: list = [1, 2, 3]
my_tuple: tuple = (1, 2, 3)
my_set: set = {1, 2, 3}
my_dict: dict = {"a": 1}
my_str: str = "dhsdjs"
# 容器类型详细注解
my_list1: list[int] = [1, 2, 3]
my_tuple1: tuple[int, bool, str] = (1, True, "dsd")
my_set1: set[int] = {1, 2, 3}
my_dict1: dict[str, int] = {"a": 1}
在注释中进行类型注解
语法:
#type:类型
代码示例
var1 = 1 # type: int
var2 = 4.56 # type: float
var3 = "sdas" # type: st
类型注解的限制
- 类型注解只是个提示,标记错了也没有关系
var1: int = "dasdsads"
var2: float = 3
var3: bool = 12321
函数注解
- 语法:
def 函数名(形参: 类型, ..., 形参: 类型) -> 返回值类型:
pass
- 代码示例
def add(x: int, y: int) -> int:
return x + y
def func(data: list) -> list:
pass
union类型
同时对多个类型进行注解
代码示例
# *_*coding:utf-8 *_*
from typing import Union
# 只是单类型的注解
my_list: list[int] = [1, 2, 3, 4]
my_dict: dict[str, int] = {"age": 12, "num": 1}
# 存在混合类型的注解
# Union[int, bool, float] 类型有可能是int, bool, float
my_list1: list[Union[int, bool, float]] = [1, True, 4.12]
my_dict1: dict[str, Union[str, int, float]] = {"name": "zs", "age": 12, "score": 85.5}
多态
完成某个行为时,使用不同的对象会得到不同的状态
代码示例
# *_*coding:utf-8 *_*
# 抽象类:含有抽象方法的类
class Animal:
# 抽象方法:方法体是空实现(pass)
def speak(self):
pass
class Cat(Animal):
def speak(self):
print("cat speak")
class Dog(Animal):
def speak(self):
print("dog speak")
def do_speak(animal: Animal):
animal.speak()
do_speak(Cat())
do_speak(Dog())