【python】对象

对象

  • 初识对象
  • 成员方法
  • 类和对象
  • 构造方法
  • 魔术方法
    • __str__字符串方法
    • __lt__小于符号比较方法
    • __le__小于等于符号比较方法
    • __eq__比较运算符实现方法
  • 封装
  • 继承
    • 基础语法
    • 复写
    • 调用父类成员
  • 类型注解
    • 为变量设置类型注解
    • 函数的类型注解-形参注解
    • Union类型
  • 多态
  • 综合案例

初识对象

设计表格-生产表格-填写表格
对应于程序中:设计类-创建对象-对象属性赋值

class Student:
	name=None
	gender=None
# 基于类创建对象
stu_1=Student()
stu_2=Student()
# 对象属性进行赋值
stu_1.name="张三"
stu_2.name="李四"
# 获取对象中记录的信息
print(stu_1.name)

成员方法

可以使用类去封装对象属性,并基于类创建出一个个对象来使用
类的使用语法

class 类名称:	# class为关键字
	类的属性		#定义在类中的变量(成员变量)
	类的行为		#定义在类中的函数(成员方法)

创建类对象的语法:

对象=类名称()

类的行为(方法):

class Student:
	name=None
	age=None
	def say_hi(self):
		print(f"我是{self.name}")

stu=Student()
stu.name="张三"
stu.say_hi()		# 输出:我是张三

可以看出类不仅可以用来定义属性、记录数据,也可以定义函数、记录行为。
在类中定义成员方法和定义函数基本一致:

def 方法名(self,形参1,...,形参N)
	方法体

self关键字是成员方法定义时必须写的,用来表示类对象自身的意思,当使用类对象调用方法,self会被python传入,在方法内部,要访问类的成员变量必须使用self

类和对象

# 设计一个闹钟类
class Clock:
	id=None
	price=None
	def ring(self):
		import winsound
		winsound.Beep(2000,3000)
# 构建2个闹钟对象并让其工作
clock1=Clock()
clock1.id="003032"
clock1.price=19.99
print(f"闹钟ID:{clock1.id},价格:{clock1.price}")
clock1.ring()
clock2=Clock()
clock2.id="003033"
clock2.price=21.99
print(f"闹钟ID:{clock2.id},价格:{clock2.price}")
clock2.ring()

构造方法

python类可以使用:init()方法,称之为构造方法
可以实现:

  • 在创建类对象时会自动执行
  • 在创建类对象时,将传入参数自动传递给__init__方法使用。
class Studengt:
	name=None
	age=None
	tel=None
	def __init__(self,name,age,tel):
		self.name=name
		self.age=age
		self.tel=tel
		print("Student类创建了一个对象")

stu=student("张三",31,"123456")

魔术方法

__str__字符串方法

当类对象需要被转换为字符串时,会输出内存地址

class Student:
	def __init__(self,name,age):
		self.name=name
		self.age=age
student=Student("张三",11)
print(student)		#<__main__.Student object at 0x000002200CFD7040>
print(str(student))		#<__main__.Student object at 0x000002200CFD7040>

可以通过__str__方法,控制类转换为字符串的行为

class Student:
	def __init__(self,name,age):
		self.name=name
		self.age=age
	def __str__(self):
		return f"Student类对象,name={self.name},age={self.age}"

student=Student("张三",11)
print(student)		# Student类对象,name=张三,age=11
print(str(student))		# Student类对象,name=张三,age=11

__lt__小于符号比较方法

直接两个对象进行比较是不可以的,但是在类中实现__lt__方法,可同时完成小于符号和大于符号比较。

class Student:
	def __init__(sefl,name,age):
		self.name=name
		self.age=age
	def __lt__(self,other):
		return self.age < other.age

stu1=Student("张三",11)
stu2=Student("李四",13)
print(stu1<stu2)	# True

__le__小于等于符号比较方法

class Student:
	def __init__(sefl,name,age):
		self.name=name
		self.age=age
	def __le__(self,other):
		return self.age <= other.age

stu1=Student("张三",11)
stu2=Student("李四",13)
print(stu1<=stu2)	# True

__eq__比较运算符实现方法

不实现__eq__方法,对象之间可以比较,但是是比较内存地址,即不同对象之间比较一定是False。

class Student:
	def __init__(sefl,name,age):
		self.name=name
		self.age=age
	def __eq__(self,other):
		return self.age == other.age

stu1=Student("张三",11)
stu2=Student("李四",13)
print(stu1==stu2)	# True

封装

将现实世界事物在类中描述为属性和方法,即为封装。

现实事物有部分属性和行为是不公开对使用者开放的。同样在类中描述属性和方法的时候也需要达到这个要求,需要定义私有成员,成员变量和成员方法的命名均以__作为开头即可。

类对象无法访问私有成员。

类中的其他成员可以访问私有成员。

在类中提供仅供内部使用的属性和方法而不对外开放(类对象无法使用)。

# 定义一个类,内含私有成员变量和私有成员方法
class Phone:
	__current_voltage=None	#当前手机运行电压
	def __keep_single_core(self):
		print("CPU以单核模式运行")

	def call_by_5g(self):
		if self.__current_voltage>=1:
			print("5g童话已开启")
		else:
			self.__keep_single_core()
			print("无法使用5g童话,以单核运行进行省电")
phone=Phone()
# phone.__keep_single_core()	
# print(phone.__current_voltage)

私有成员无法被类对象使用,但是可以被其它的成员使用。

继承

基础语法

# 单继承
class phone:
	IMEI=None	#序列号
	producer=None	#厂商
	def call_by_4g(self):
		print("4g通话")

class phone2022(phone):
	face_id=True	# 面部识别
	def call_by_5g(self):
		print("2022最新5g通话")
# 多继承
class Myphone(phone, NFCReader, RemoteControl):
	pass

pass是占位语句,用来保证函数(方法)或类定义的完整性,表示无内容,空的意思。

class 类名(父类1, 父类2, ..., 父类N):
	类内容体

多继承注意事项:多个父类中,如果有同名的成员,那么默认以继承顺序(从左到右)为优先级。即先继承的保留,后继承的被覆盖。

复写

子类继承父类的成员属性和成员方法后,通过在子类中重新定义同名的属性或方法进行复写。

调用父类成员

一旦复写父类成员,那么类对象调用成员时,就会调用复写后的新成员。
如果需要使用被复写的父类的成员,需要特殊的调用方式:

# 调用父类成员
# 使用成员变量:父类名.成员变量
# 使用成员方法:父类名.成员方法(self)
# 使用super()调用父类成员
# 使用成员变量:super().成员变量
# 使用成员方法:super().成员方法()

注意:只可以在子类内部调用父类的同名成员,字类的实体类对象调用默认调用子类复写

类型注解

当调用方法进行传参的时候,ctrl+p弹出提示:

import random
random.randint()

传入2个参数,类型是int

内置模块random的方法可以提示类型,而自定义的不可以。因为pycharm无法通过代码确定应传入什么类型,需要使用类型注解。

类型注解:在代码中涉及数据交互的地方,提供数据类型的注解(显示的说明)。帮助第三方IDE工具(如pycharm)对代码进行类型推断,协助做代码提示;帮助开发者自身对变量进行类型注释,并不会对类型做验证和判断。

支持:变量的类型注解;函数(方法)形参列表和返回值的类型注解

为变量设置类型注解

基础语法:变量:类型

# 基础数据类型注解
var_1:int = 10
var_2:float=3.14
var_3:bool=True
var_4:"itheima"
# 类对象类型注解
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={"itheima":666}
my_str:str="itheima"
# 容器类型详细注解
my_list:list[int]=[1,2,3]
my_tuple:tuple[str,int,bool]=("itheima",666,True)
my_set:set[int]={1,2,3}
my_dict:dict[str,int]={"itheima":666}

元组类型设置类型详细注解,需要将每一个元素都标记出来。
字典类型设置类型详细注解,需要2个类型,第一个是key第二个是value。
为变量设置注解,显示的变量定义,一般无需注解。无法直接看出变量类型之时会添加变量的类型注解。

也可以在注释中进行类型注解
语法:# type:类型

class Student:
	pass
var_1=random.randint(1,10)	# type: int
var_2=json.loads(data)		# type: dict[str,int]
var_3=func()				# type: Student

类型注解只是提示性的,并非决定性的。数据类型和注解类型无法对应也不会导致错误。

函数的类型注解-形参注解

def func(data):
	data.app
func()

在编写函数(方法),使用形参data的时候,工具没有任何提示;在调用函数(方法),传入参数的时候,工具无法提示参数类型。因为在定义函数(方法)的时候没有给形参进行注解。
函数和方法的形参类型注解语法:
同时,函数(方法)的返回值也可以添加类型注解。

def 函数方法名(形参名:类型,形参名:类型,...)->返回值类型:
	pass

Union类型

使用Union[类型,...,类型]可以定义联合类型注释

from typing import Union	# 必须先导包
my_list:list[Union[str,int]]=[1,2,"itheima","itcast"]
my_dict:dict[str,Union[str,int]]={"name":"张三","age":31}
def func(data: Union[int, str])->Union[int, str]:
	pass

多态

完成某个行为时,使用不同的对象会得到不同的状态。

class Animal:
	def speak(self):
		pass
class Dog(Animal):
	def speak(self):
		print("汪汪汪")
class Cat(Animal):
	def speak(self):
		print("喵喵喵")
def make_noise(animal:Animal):
	animal.speak()
dog=Dog()
cat=Cat()
make_noise(dog)		#输出:汪汪汪
make_noise(cat)		#输出:喵喵喵

多态常作用在继承关系上。比如函数(方法)形参声明接收父类对象,实际传入父类的子类对象进行工作,即以父类做定义声明、以子类做实际工作、用以获得同一行为不同状态。

抽象类(接口):包含抽象方法的类。抽象方法指没有具体实现的方法(pass)。
抽象类就好比定义一个标准,包含了一些抽象的方法,要求子类必须实现。多用于顶层设计,以便子类做具体实现,也是对子类的一种软性约束,要求子类必须复写(实现)父类的一些方法,并配合多态,完成不同的工作状态。

抽象的父类设计(设计标准);具体的子类实现(实现标准)

综合案例

  1. 使用面向对象思想完成数据读取和处理
  2. 基于面向对象思想重新认知第三方库使用(PyEcharts)

你可能感兴趣的:(python,开发语言)