本章内容:以一种深入浅出的方式认识类和对象。
所有相关代码可在https://github.com/hzyao/Python-Cookbook
进行查看。边学习边实操,及时挖掘真美妙!搭配食用或许口味更佳哟!
类和对象
生活中,我们可以使用设计表格、生产表格、填写表格的形式组织数据。来!咱们把它和程序中的类对比一下!
- 设计表格 —— 设计类(class)
- 打印表格 —— 创建对象
- 填写表格 —— 对象属性赋值
也就是说我们可以使用类去封装属性,并基于类创建出一个个的对象来使用。
1 类和对象
类的使用语法:
class 类名称:
类的属性
类的行为
对象 = 类名称()
"""
1. class是关键字,表示要定义类啦
2. 类的属性,即定义在类中的变量(成员变量)
3. 类的行为,即定义在类中的函数(成员方法)
"""
类的行为(方法)到底是啥子呢?
class Student:
name = None
age = None
def say_hi(self):
print(f"嗨大家好!我是{
self.name}")
Student.name = "run"
Student.age = 18
print(Student.name)
print(Student.age)
从上面我们可以看出,类中不仅可以定义属性用来记录数据,也可以定义函数,用来记录行为。其中:
- 类中定义的属性(变量),我们把它叫做:成员变量
- 类中定义的行为(函数),我们把它叫做:成员方法
以后,咱们就把定义在类内部的函数叫做方法了噢!
成员方法的定义语法:
在类中定义成员方法和定义函数基本一致,但仍有细微区别:
def 方法名(self, 形参1, ......, 形参N):
方法体
在方法定义的参数列表中,有一个self
关键字,self
关键字是成员方法定义的时候必须要填写的。它用来表示类对象本身的意思,当我们使用类对象调用方法的是,self
会自动被python传入。在方法内部,想要访问类的成员变量,必须使用self
。
注:self
关键字,尽管出现在参数列表中,但是不占用参数位置,传参的时候可以忽略它。
class Student:
name = None
def say_hi(self):
print(f"Hello 大家好 我是{
self.name}")
def say_hi2(self, msg):
print(f"Hello 大家好 我是{
self.name} {
msg}")
stu1 = Student()
stu1.name = "run"
stu1.say_hi() # 调用的时候无需传参
stu1.say_hi2("很高兴认识大家!") # 调用的时候,需要传msg参数
stu2 = Student()
stu2.name = "xmy"
stu2.say_hi()
stu2.say_hi2("嘿嘿嘿!")
在传入参数的时候,self
可以说是是透明的,不用理它!参数msg
各玩各的!
所以,类和成员方法的定义语法如下:
class 类名称:
成员变量
def 成员方法(self, 参数列表):
成员方法体
对象 = 类名称()
我们已经了解到,基于类创建对象的语法为对象 = 类名称()
。
那么我们为什么一定要创建对象才能使用呢?
类只是一种程序内的“设计图纸”,需要基于图纸产生实体(也就是对象),才能正常工作。这种套路就是我们所说的“面向对象编程” —— 设计类,基于类创建对象,使用对象来完成具体的工作。
# 练习:设计一个闹钟类
class Clock:
id = None # 序列号
price = None # 价格
def ring(self):
print("beep")
clock1 = Clock()
clock1.id = "1220"
clock1.price = 9.99
print(f"id is {
clock1.id}, price is {
clock1.price}")
clock1.ring()
clock2 = Clock()
clock2.id = "0324"
clock2.price = 8.88
print(f"id is {
clock2.id}, price is {
clock2.price}")
clock2.ring()
2 使用构造方法向成员变量赋值
在之前的学习中,我们为对象的属性赋值需要依次进行,略显繁琐。其实呀,咱们可以用更高效的方式把这个搞定!就像函数传参那种形式一样对属性进行赋值!
Python 的类可以使用**__init__()**
方法,称为构造方法。
- 在创建类对象(构造类)的时候,会自动执行。
- 在创建类对象(构造类)的时候,将传入参数自动传递给__init__方法使用。
# 构造方法的名称:__init__
class Student:
name = None
age = None
tel = None # 这些可以省略
def __init__(self, name, age, tel):
self.name = name
self.age = age
self.tel = tel
print("done")
stu = Student("run", 18, "0324")
print(stu.name)
print(stu.age)
print(stu.tel)
注:构造方法也是成员方法,不要忘记在参数列表中提供self
;且在构造方法内定义成员变量,需要使用关键字self
。
# 练习:学生信息录入
class Student:
def __init__(self):
self.name = input("请输入学生姓名:")
self.age = int(input("请输入学生年龄:"))
self.address = input("请输入学生地址:")
for i in range(1, 11):
print(f"当前录入第{
i}位学习信息,总共需录入10位学习信息")
stu = Student()
print(f"学生{
i}信息录入完成,信息为:【学生姓名:{
stu.name}, 年龄:{
stu.age}, 地址:{
stu.address}】")
3 其他内置类方法
由于这些内置的类方法,各自有其各自特殊的功能,所以我们把它们称为魔术方法。
魔术方法非常非常多,我们先了解常见的即可!例如:__init__
(构造方法)、__str__
(字符串方法)、__lt__
(大于、小于符号比较)、__le__
(大于等于、小于等于符号比较)、__eq__
(==符号比较)等。
3.1 str:字符串方法
功能:控制类转换为字符串的行为。
- 方法名:
__str__
- 返回值:字符串
- 内容:自行定义
# __str__ 字符串方法
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
stu = Student("run", 18)
print(stu)
print(str(stu)) # 会输出内存地址
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"name:{
self.name}, age:{
self.age}"
stu = Student("run", 18)
print(stu)
print(str(stu))
3.2 lt:<、> 符号比较
功能:直接对2个对象进行比较是不可以的,但是在类中实现__lt__
方法,即可同时完成:大于符号和小于符号的2种比较。
- 方法名:
__lt__
- 传入参数:
other
,另一个类对象 - 返回值:
True
orFalse
- 内容:自行定义
# __lt__ 方法
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __lt__(self, other):
return self.age < other.age
stu1 = Student("run", 18)
stu2 = Student("xmy", 16)
print(stu1 < stu2) # False
print(stu1 > stu2) # True
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
stu1 = Student("run", 18)
stu2 = Student("xmy", 16)
print(stu1 < stu2) # 无法比较会报错
3.3 le:<=、>= 符号比较
功能:可用于 <=、>= 两种比较运算符上。
- 方法名:
__le__
- 传入参数:other,另一个类对象
- 返回值:
True
orFalse
- 内容:自行定义
# __le__ 方法
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __le__(self, other):
return self.age <= other.age
stu1 = Student("run", 18)
stu2 = Student("xmy", 16)
print(stu1 <= stu2) # False
print(stu1 >= stu2) # True
3.4 eq:== 符号比较
功能:可用于 == 比较运算符上。
- 方法名:
__eq__
- 传入参数:other,另一个类对象
- 返回值:
True
orFalse
- 内容:自行定义
# __eq__ 方法
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __eq__(self, other):
return self.age == other.age
stu1 = Student("run", 18)
stu2 = Student("xmy", 18)
print(stu1 == stu2) # False
总结:
__init__
:构造方法,可用于创建类对象的时候设置初始化行为;
__str__
:用于实现类对象转字符串的行为;
__lt__
:用于两个类对象进行小于或大于比较;
__le__
:用于两个类对象进行小于等于或大于等于比较;
__eq__
:用于两个类对象进行相等比较。