Python中class的学习心得
在学习Python的时候,前面各类知识较为容易,唯独对class
这的数据格式迷迷糊糊,这段时间学习了相关内容,给大家分享一下个人学习心得。
class的入门理解
在给出枯燥的基础知识之前,我更想要让大家对class
有个基本概念。
场景1
玩游戏时。最开始要对人物初始化,比如人物的性别、技能、属性……
一开始,大家基本都一样,新建玩家时,玩家那么多,一遍又一遍的Ctrl+C
配合Ctrl+V
太过麻烦。
class
就有用武之地了,只需要新建class
内含的属性即可,后续可以直接赋值。
批量生产就是不一样。
场景2
大家都经历过考试,都有过分数和排名,也都见过班级成绩排名,他基本上都是这样的:
姓名 |
语文 |
数学 |
英语 |
物理 |
化学 |
总分 |
排名 |
王二 |
|
|
|
|
|
|
张三 |
|
|
|
|
|
|
李四 |
|
|
|
|
|
|
钱五 |
|
|
|
|
|
|
对于谁来说,都得要考这些科目,都会有各科目的分数。
就像老师录入分数一样,他只会使用同一个表头,然后依次输入每位同学的分数。
class
也是这样,它的作用就是这个表头。
基础语法
class ClassName:
<statement_1>
.
.
.
<statement_N>
这其中的<statement_i>
有两种,分别是属性和方法
属性很好理解,就像你的籍贯一样,你出生后就是跟随一辈子的。只要创建了一个class
,这个对象的属性就是初始设置好的。例如:
class MyInfo:
nation = "中国"
这么一来,无论是谁的nation
初始化都会是中国,不会因为变量名不同而有所差异。
此时,我们只需要这么做就赋予了变量中国国籍:
# 实例化类
wzscrn = MyInfo()
# 访问类的属性
print(f"wzscrn的国籍是{wzscrn.nation}。") # 这里可以自行搜索Python中的f-string用法
当然,向精确地方?简单,直接修改就好了。
# 实例化类
wzscrn.nation = "中国江苏"
# 访问类的属性
print(f"wzscrn的所在地是{wzscrn.nation}。")
方法说白了就是类内嵌的函数。
class MyScore:
Chinese = 0
Math = 0
English = 0
Physics = 0
Chemistry = 0
def Total_Score(self):
return self.Chinese+self.Math+self.English+self.Physics+self.Chemistry
好吧,我猜你想问self
是个啥,self
不就是自己本身吗?
也就是说,这是函数,如果创建了一个类,那么后续函数的变量要用这个类本身的属性。
就好比说,给你算总分,不能把王二麻子的数学得分算到你的头上吧。
可是程序是笨笨的,必须要有严格的指定。
说到这里,类的语法基本上说完了。
是的,就这两类,就这么简单。
class的简单示例
那么现在我们是班主任了,真得给学生录入分数了。
那么先得创建类。
class ClassScore:
Chinese = 0
Math = 0
English = 0
Physics = 0
Chemistry = 0
def Total_Score(self):
return self.Chinese+self.Math+self.English+self.Physics+self.Chemistry
好啦,赶快把你们班同学的姓名录进去吧。
wanger = ClassScore()
zhangsan = ClassScore()
lisi = ClassScore()
qianwu = ClassScore()
别停,大家现在都是0分呢,赶快录入分数吧。
wanger.Chinese = 75
wanger.Math = 85
wanger.English = 69
wanger.Physics = 82
wanger.Chemistry = 89
.
.
.
class的高级语法
累吧?就是让你一个个输到不想打字了。毕竟懒人推动世界进步
构造函数(__init__
方法)
该怎样依次输入姓名和各科成绩就能直接给对象赋值了呢?
这就用用到构造函数__init__
了
构造函数是在创建对象时自动调用的方法,用于初始化对象的属性。
class Stu_Score:
def __init__(self, name, chinese, math, english, physics, chemistry):
self.name = name
self.chinese = chinese
self.math = math
self.english = english
self.physics = physics
self.chemistry = chemistry
def total_score(self):
return self.chinese + self.math + self.english + self.physics + self.chemistry
# 实例化对象
wanger = Stu_Score("王二", 75, 85, 69, 82, 89)
print(f"{wanger.name}的总分是{wanger.total_score()}")
这下是不是非常简单了?只需要输入这几个分数即可,不需要再像上面挨个输入属性赋值啦。
2. 继承
继承是面向对象编程的一个核心概念,它允许我们创建一个新的类(称为子类)来继承一个或多个现有类(称为父类或基类)的属性和方法。
class Person:
def __init__(self, name):
self.name = name
def greet(self):
return f"Hello, my name is {self.name}."
class Student(Person):
def __init__(self, name, chinese, math, english, physics, chemistry):
super().__init__(name) # 调用父类的构造函数
self.chinese = chinese
self.math = math
self.english = english
self.physics = physics
self.chemistry = chemistry
def total_score(self):
return self.chinese + self.math + self.english + self.physics + self.chemistry
# 实例化对象
wanger = Student("王二", 75, 85, 69, 82, 89)
print(wanger.greet())
print(f"{wanger.name}的总分是{wanger.total_score()}")
3. 多态
多态允许你将子类对象用作父类对象,从而实现接口的多种不同表现形式。在Python中,由于鸭子类型(duck typing)的存在,多态性天然得到支持。
例如,现在要来编写模拟动物发声的程序,你需要先设定动物属性,然后再具体指定某一动物的叫声。
class Animal:
def speak_sound(self):
raise NotImplementedError("未指定具体动物")
class Dog(Animal):
def speak_sound(self):
return "汪汪汪"
class Cat(Animal):
def speak_sound(self):
return "喵喵喵"
# 多态性
animals = [Dog(), Cat()]
for animal in animals:
print(animal.speak())
4. 封装
封装是将数据和操作数据的函数绑定在一起,形成一个不可分割的整体。通过访问控制(如私有属性),你可以限制对对象属性的直接访问。
class Student:
def __init__(self, name, chinese, math, english, physics, chemistry):
self.__name = name
self.chinese = chinese
self.math = math
self.english = english
self.physics = physics
self.chemistry = chemistry
@property
def name(self):
return self.__name
def total_score(self):
return self.chinese + self.math + self.english + self.physics + self.chemistry
# 实例化对象
wanger = Student("王二", 75, 85, 69, 82, 89)
print(wanger.name) # 访问私有属性通过@property装饰器
# print(wanger.__name) # 这将引发AttributeError,因为__name是私有属性
完整示例:学生成绩管理系统
下面是一个综合示例,展示如何使用类、构造函数、继承、多态和封装来创建一个简单的学生成绩管理系统。
class Person:
def __init__(self, name):
self.__name = name
def name(self):
return self.__name
class Student(Person):
def __init__(self, name, chinese, math, english, physics, chemistry):
super().__init__(name)
self.chinese = chinese
self.math = math
self.english = english
self.physics = physics
self.chemistry = chemistry
def total_score(self):
return self.chinese + self.math + self.english + self.physics + self.chemistry
def __str__(self):
return f"{self.name()}:语文{self.chinese}分,数学{self.math}分,英语{self.english}分,物理{self.physics}分,化学{self.chemistry}分,共计{self.total_score()}分"
# 创建一个学生列表
students = [
Student("王二", 75, 85, 69, 82, 89),
Student("张三", 88, 76, 90, 84, 81),
Student("李四", 92, 88, 77, 91, 85),
Student("钱五", 85, 93, 84, 96, 98)
]
# 打印学生信息
for student in students:
print(student)
点餐系统的示例
编写一个选零食系统,各个零食相关的资料如下:
|
Popcorn |
Ice Cream |
Chocolate |
Pretzels |
Chips |
Candy |
Cookies |
Cola |
Soda |
Taste |
9 |
9 |
8 |
8 |
7 |
7 |
7 |
6 |
6 |
Price |
6 |
6 |
4 |
4 |
5.5 |
2 |
4 |
3.5 |
3.5 |
请编写一个可以根据预算分别依据Taste、Price和Taste-to-Price ratio给出零食选择建议。
代码如下:
class Snack(object):
def __init__(self, n, v, w):
self.name = n
self.taste = v
self.price = w
def getTaste(self):
return self.taste
def getPrice(self):
return self.price
def density(self):
return self.taste / self.price
def buildMenu(names, tastes, prices):
menu = []
for i in range(len(names)):
menu.append(Snack(names[i], tastes[i], prices[i]))
return menu
def greedy(items, maxPrice, keyFunction):
itemsCopy = sorted(items, key=keyFunction, reverse=True)
result = []
totalTaste = 0
totalPrice = 0
for i in range(len(itemsCopy)):
if (totalPrice + itemsCopy[i].getPrice()) <= maxPrice:
result.append(itemsCopy[i])
totalTaste += itemsCopy[i].getTaste()
totalPrice += itemsCopy[i].getPrice()
return result, totalTaste, totalPrice
def testGreedys(snacks, maxPrice):
print('\nSelection based on taste score: ')
result, totalTaste, totalPrice = greedy(snacks, maxPrice, keyFunction=lambda x: x.getTaste())
print('Total taste scores: {:.1f}, total cost: $ {:.1f}'.format(totalTaste, totalPrice))
for s in result:
print(f" {s.name}: <{s.taste},{s.price}>")
print('\nSelection based on price: ')
result, totalTaste, totalPrice = greedy(snacks, maxPrice, keyFunction=lambda x: - x.getPrice())
print('Total taste scores: {:.1f}, total cost: $ {:.1f}'.format(totalTaste, totalPrice))
for s in result:
print(f" {s.name}: <{s.taste},{s.price}>")
print('\nSelection based on taste-to-price ratio: ')
result, totalTaste, totalPrice = greedy(snacks, maxPrice, keyFunction=lambda x: x.density())
print('Total taste scores: {:.1f}, total cost: $ {:.1f}'.format(totalTaste, totalPrice))
for s in result:
print(f" {s.name}: <{s.taste},{s.price}>")
snacks = buildMenu(['Popcorn', 'Ice Cream', 'Chocolate', 'Pretzels', 'Chips', 'Candy', 'Cookies', 'Cola', 'Soda'], [9, 9, 8, 8, 7, 7, 7, 6, 6], [6, 6, 4, 4, 5.5, 2, 4, 3.5, 5.5])
maxPrice = eval(input("Enter the total budget($): "))
testGreedys(snacks, maxPrice)