Week11 - Designed with classes
- 什么class?
类是用户定义的数据类型,其中包含属性和方法。类定义事物(对象)的抽象特征,包括其特征(字段或属性)和行为(它可以做的事情或方法)。
- 为什么要用class?
因为写一个class以后可以多次调用,一劳永逸。我们可以在一个class下定义多个对象,如果没有写class我们需要对每一个对象进行解释其方法和属性。
- class(类)与 object (对象)的区别?
类就是一个模板,模板里可以包含多个函数,函数里实现一些功能。
对象则是根据模板创建的实例,通过实例对象可以执行类中的函数。
总之,类是对象的蓝图。对象是属于类的实例。
其实我们之前已经用了许多class方法了,例如:我们在 里定义mywindow是Tk()类的一个对象(即定义窗口);在 里定义 是turtle.Turtle()类的一个对象(即定义画笔)……
例 1 :
class Student(object):
def __init__(self,id,name,age): #初始化方法,来初始化新创建对象的状态
self._id = id
self._name = name
self._age = age
# 类里定义的函数方法
def getId(self):
return self._id
def getName(self):
return self._name
def getAge(self):
return self._age
def __str__(self): # 转化为str类型输出
return "Hello , "+ self._name + "\nYour ID is " + self._id + "\nYour are " + str(self._age)
s = Student("s777777","whh",19) #s作为一个对象去调用Student类,括号里的是要传进去的参数
print (s)
解析:
- 在一个类里,一般都会定义def init(self):函数,这是初始化新创对象状态的。注意,init前后都是两个下划线。
- " 双下划线 " 开始的是私有成员,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据。
- "单下划线 " 开始的成员变量叫做保护变量,意思是只有类实例和子类实例能访问到这些变量
- 类中的函数第一个参数必须是self
注意:
在同一个py文件里写class并调用直接写 class名(参数)就可以调用了,如果在一个py文件里想调用其他py文件里的class需要用 from py文件名 import class名,如下:
from test import Student # 我写Student类的py文件在同一个目录下且文件名是test
s = Student("s777777","whh",19)
print (s)
运行出来结果是一样的。
例 2 :
class pizzaorder(object):
def __init__(self,name,size,number):
self._name = name
self._size = size
self._number = number
def getPrize(self):
prize = 0
if self._size == "small":
prize = 8.00
if self._size == "Medium":
prize = 10.00
if self._size == "large":
prize = 12.00
return prize
def getcost(self):
return self.getPrize() * self._number
def __str__(self):
return "Name of pizza : " + self._name + "\nSize of pizza: " + self._size + "\nNumber of pizza: " + str(self._number) + "\nPrize of pizza: " + str(self.getPrize()) + "\nTotal cost: " + str(self.getcost())
p = pizzaorder("Vegetable pizza","small",3)
print (p)
运行结果:
解析:
大家应该发现了,在class里写东西就开始多一个__init__初始化,最后有一个__str__转字符型输出,然后把变量写成self._ 变量名 ,函数写成self.函数名的形式即可。
例 3 :
我们在例2的基础下再设置一个是否加芝士的选项。
class pizzaorder(object):
def __init__(self,name,size,number):
self._name = name
self._size = size
self._number = number
self._EXCHS = 2
def getPrize(self):
prize = 0
if self._size == "small":
prize = 8.00
if self._size == "Medium":
prize = 10.00
if self._size == "large":
prize = 12.00
return prize
def setextrachesse(self,extChesse):
self._extrancheese = extChesse
if self._extrancheese:
self._cheese = "extra cheese"
else:
self._cheese = "No cheese"
def getcost(self):
cost = 0
if self._extrancheese:
cost = (self.getPrize()+self._EXCHS)*self._number
else:
cost = self.getPrize()*self._number
return cost
def __str__(self):
return "Name of pizza : " + self._name + "\nSize of pizza: " + self._size + "\nNumber of pizza: " + str(self._number) + "\nPrize of pizza: " + str(self.getPrize()) + "\nCheese: " + self._cheese + "\nTotal cost: " + str(self.getcost())
p = pizzaorder("Vegetable pizza","small",3)
p.setextrachesse(True)
print (p)
运行结果:
例 4 :
在例2的基础下我们加上成绩列表(list)。
class Student(object):
def __init__(self,id,name,age,number): #初始化方法,来初始化新创建对象的状态
self._id = id
self._name = name
self._age = age
self._mark = []
for i in range(number):
self._mark.append(0)
def getmark(self,i,score):
self._mark[i-1] = score
def __str__(self): # 转化为str类型输出
return "Hello , "+ self._name + "\nYour ID is " + self._id + "\nYour are " + str(self._age) + "\nMarks : " + str(self._mark)
s = Student("s777777","whh",19,3)
s.getmark(1,90)
s.getmark(2,95)
s.getmark(3,94)
print (s)
运行结果:
注意:
要想输出mark列表内的全部值需要输出self._mark
例 5:
这里我们写一个学生买不同类别的课程后计算总价格的题目。
先建一个文件去构造class类,文件名我们命名为test:
class fee(object):
def __init__(self,name,type,num):
self._name = name
self._type = type
self._num = num
def getname(self): # 输出姓名
return self._name
def gettype(self): # 输出课程类型
return self._type
def getnum(self): # 输出课程数量
return self._num
def getprize(self):
prize = 0 # 判断价格
if self._type == "C":
prize = 400
if self._type == "D":
prize = 500
if self._type == "H":
prize = 650
return float(prize)
def getcost(self): # 计算总价格
return float(self.getprize() * self._num)
def __str__(self): # 格式化输出
return "\n********* Fee Calculations *********\n" + "\nFee calculation for " + self.getname() + "\nSingle subject cost = $ " + str(self.getprize()) + "\nFor " + str(self.getnum()) + " subjects total cost = $ " + str(self.getcost())
之后我们写一个交互程序去调用这个class方法:
from test import fee # 调用fee类
def main():
print("------------- Scholar Online Academy - Fee Calculator ------------")
"""
Data validation
"""
while True :
try :
name = str(input("Please enter your name:"))
type = str(input("Please enter course (C - Cert IV , D - Diploma or H - Higher Diploma)"))
num = int(input("How many subjects?"))
except ValueError:
print ("Sorry , please input the value with the rules.")
else:
type = type.upper()
if type == "C" or type == "D" or type == "H":
break
print("The type is in wrong type.")
print (fee(name,type,num))
main()
运行结果:
------------- Scholar Online Academy - Fee Calculator ------------
Please enter your name:whh
Please enter course (C - Cert IV , D - Diploma or H - Higher Diploma)D
How many subjects?3
********* Fee Calculations *********
Fee calculation for whh
Single subject cost = $ 500.0
For 3 subjects total cost = $ 1500.0
解析:
这里的Data Validation(数据验证)值得学习。既控制了数据类型,又防止用户输入无效选型。
例 6:
根据所租大厅的种类和时间来计算总价格。
先构造class类:
class VenueBooking (object):
# 初始化变量
def __init__(self,name,date,capacity,hour):
self._name = name
self._date = date
self._capacity = capacity
self._hour = hour
"""
定义get方法系列
"""
def getname(self):
return self._name
def getdate(self):
return self._date
def getcapacity(self):
return self._capacity
def gethour(self):
return self._hour
# 判断价格
def getprize(self):
prize = 0
if self._capacity == "S":
prize = 1400
if self._capacity == "M":
prize = 1500
if self._capacity == "L":
prize = 1650
return prize
# 计算总价格
def getcost(self):
return self.getprize()*self._hour
# 格式化输出
def __str__(self):
return "\n********* Booking Fee Calculations *********\n" \
+ "\nBooking fee calculation for " + self._name \
+ " on " + self._date + "\nHourly booking cost = $ " \
+ f'{self.getprize():<.2f}' + "\nTotal booking cost = $ " \
+ f'{self.getcost():<.2f}' + " for " + str(self._hour) + " hours."
再来一个调用此class类的py文件:
from test import VenueBooking
def main(): # 定义一个main()函数
print ("------------ Gala Functions - Booking System ------------") # 打印title
while True:
try:
name = str(input("Please input customer name:"))
date = str(input("Please input booking date:"))
print ()
print("Booking cost depends on the venue capacity and the booking period\nS - (50 - 100 guests), M - (100 - 200 guests), L - (200 - 300 guests)")
capacity = str(input("Please select your venue capacity option : "))
hour = int(input("Booking period (hours)?"))
except ValueError:
print("Sorry , please input your value with the rules.") #错误提示
else:
capacity = capacity.upper() #兼容大小写
"""
判断时间和类型是否达标
若不达标则分别提示
"""
if hour <= 12:
if capacity == "S" or capacity == "M" or capacity == "L":
break
else:
print("The capacity is in wrong type.")
else:
print("Please input the hours under 12 .")
print(VenueBooking(name,date,capacity,hour)) # 调用class类
main() #调用main函数
解析:
这个和上一个大体一致,但有几个注意点:
- 反斜杠(\)可当连字符使用
- 这里保留到小数点的后两位可以用 f’{变量名:< .2f}'在格式化输出
- 在Data Validation中要判断两种类型的数据是否规范,并输出不同提示修改的语句。我们可以用if镶嵌来实现。