面向对象编程是最有效的软件编写方法之一。
在面向对象编程中, 你编写表示现实世界中的事物和情景的类,并基于这些类来创建对象。 编写类时,你定义一大类对象都有的通用行为。基于类创建对象时, 每个对象都自动具备这种通用行为,然后可根据需要赋予每个对象独 特的个性。使用面向对象编程可模拟现实情景,其逼真程度达到了令 你惊讶的地步。
创建和使用类
创建Dog类
根据Dog类创建的每个实例都将存储名字和年龄。我们赋予了每条小狗蹲下(sit())和打滚
(roll_over())的能力
class Dog():
"""a dog play"""
def __init__(self,name,age):
"""name and age"""
self.name = name
self.age = age
def sit(self):
"""sit down"""
print(self.name.title() + "is now sitting")
def roll_over(self):
"""roll over"""
print(self.name.title() + "is now roll over")
根据类创建实例
访问属性
my_dog = Dog('willie', 6)
print("My dog's name is " + my_dog.name.title() + ".")
print("My dog is " + str(my_dog.age) + " years old.")
调用方法
my_dog.sit()
my_dog.gun()
#
My dog's name is Willie.
My dog's age is 6.
Willie is siting
Willie is guning
练习:
创建一个名为Restaurant的类,其方法init()设置两个属性:restaurant_name和cuisine_type。
创建一个名为describe_restaurant()的方法和一个名为open_restaurant()的方法,其中前者打印前述两项信息,
而后者打印一条消息,指出餐馆正在营业
class Restaurant():
def __init__(self,restaurant_name,cuisine_type):
self.restaurant_name = restaurant_name
self.cuisine_type = cuisine_type
def describe_restaurant(self):
print(self.restaurant_name + " de " + self.cuisine_type)
def open_restaurant(self):
print("can guan working")
dayin = Restaurant('xiaojin','chuan cai')
dayin.describe_restaurant()
dayin.open_restaurant()
#
xiaojin de chuan cai
can guan working now
使用类和实例
Car 类
class Car():
def __init__(self,paizi,xinghao,nianfen):
self.paizi = paizi
self.xinghao = xinghao
self.nianfen = nianfen
def che(self):
long = self.paizi + ' ' + self.xinghao + ' ' + self.nianfen
return long.title()
car = Car('aodi','a4','2020')
print(car.che())
#Aodi A4 2020
给属性指定默认值
class Car():
def __init__(self,paizi,xinghao,nianfen):
self.paizi = paizi
self.xinghao = xinghao
self.nianfen = nianfen
self.licheng = 0
def che(self):
long = self.paizi + ' ' + self.xinghao + ' ' + self.nianfen
return long.title()
def a_licheng(self):
print("This car has " + str(self.licheng) + " miles on it.")
my_car = Car('aodi','a4','2020')
print(my_car.che())
my_car.a_licheng()
#
Aodi A4 2020
This car has 0 miles on it.
修改属性的值
可以以三种不同的方式修改属性的值:直接通过实例进行修改;通过方法进行设置;通过方法进行递增(增加特定的值)。下面依次介绍这些方法
- 直接修改属性的值要修改属性的值,最简单的方式是通过实例直接访问它。
my_car.licheng = 22
my_car.a_licheng()
#
Aodi A4 2020
This car has 22 miles on it.
2.通过方法修改属性的值
如果有替你更新属性的方法,将大有裨益。这样,你就无需直接访问属性,而可将值传递给一个方法,由它在内部进行更新
def up(self,updata):
self.licheng = updata
car = Car('aodi','a6','2020')
car.xinxi()
car.up(23)
car.li()
- 通过方法对属性的值进行递增
有时候需要将属性值递增特定的量,而不是将其设置为全新的值。假设我们购买了一辆二手车,且从购买到登记期间增加了100英里的里程,下面的方法让我们能够传递这个增量,并相应地增加里程表读数
class Car():
def __init__(self,paizi,xinghao,nianfen):
self.paizi = paizi
self.xinghao = xinghao
self.nianfen = nianfen
self.licheng = 22
def xinxi(self):
xinxis = self.xinghao + " " + self.xinghao + " " + self.nianfen + "."
return xinxis.title()
def li(self):
print("This car has " + str(self.licheng) + " miles on it.")
def up(self,updata):
if updata >= self.licheng:
self.licheng = updata
else:
print("You can't roll back an odometer!")
def ershou(self,ershoun):
self.licheng += ershoun
car = Car('aodi','a6','2020')
car.xinxi()
car.up(200)
car.li()
car.ershou(100)
car.li()
#
a6 a6 2020.
This car has 200 miles on it.
This car has 300 miles on it.
练习:
#创建一个名为Restaurant的类,其方法__init__()设置两个属性:restaurant_name和cuisine_type。
# 创建一个名为describe_restaurant()的方法和一个名为open_restaurant()的方法,其中前者打印前述两项信息,
# 而后者打印一条消息,指出餐馆正在营业
#9-4 就餐人数:在为完成练习9-1而编写的程序中,添加一个名为number_served的属性,并将其默认值设置为0。
# 根据这个类创建一个名为restaurant的实例;打印有多少人在这家餐馆就餐过,然后修改这个值并再次打印它。
# 添加一个名为set_number_served()的方法,它让你能够设置就餐人数。调用这个方法并向它传递一个值,然后再次打印这个值。
# 添加一个名为increment_number_served()的方法,它让你能够将就餐人数递增。调用这个方法并向它传递一个这样的值:
# 你认为这家餐馆每天可能接待的就餐人数.
class Restaurant():
def __init__(self,restaurant_name,cuisine_type):
self.restaurant_name = restaurant_name
self.cuisine_type = cuisine_type
self.number_served = 0
def describe_restaurant(self):
print(self.restaurant_name + ' ' + self.cuisine_type)
def open_restaurant(self):
print("this working now!")
def restaurant(self):
print("yi gong you ke ren :" + str(self.number_served)+ " ge")
def set_number_served(self,num):
self.number_served = num
def increment_number_served(self,innum):
self.number_served += innum
caiguan = Restaurant('jintianyu','chuan cai')
caiguan.describe_restaurant()
caiguan.set_number_served(23)
caiguan.restaurant()
caiguan.increment_number_served(10)
caiguan.restaurant()
#
jintianyu chuan cai
yi gong you ke ren :23 ge
yi gong you ke ren :33 ge
继承
编写类时,并非总是要从空白开始。如果你要编写的类是另一个现成类的特殊版本,可使用继承。一个类继承另一个类时,它将自动获得另一个类的所有属性和方法;原有的类称为父类,而新类称为子类。子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法
子类的方法init()
class Car():
def __init__(self,paizi,xinghao,nianfen):
self.paizi = paizi
self.xinghao = xinghao
self.nianfen = nianfen
self.licheng = 22
def xinxi(self):
xinxis = self.paizi + " " + self.xinghao + " " + self.nianfen + "."
return xinxis.title()
def li(self):
print("This car has " + str(self.licheng) + " miles on it.")
def up(self,updata):
if updata >= self.licheng:
self.licheng = updata
else:
print("You can't roll back an odometer!")
def ershou(self,ershoun):
self.licheng += ershoun
class Diancar(Car):
def __init__(self,paizi,xinghao,nianfen):
super().__init__(paizi,xinghao,nianfen)
tesila = Diancar('tesila','S1','2020')
print(tesila.xinxi())
#Tesila S1 2020.
super()是一个特殊函数,帮助Python将父类和子类关联起来。这行代码让Python调用 ElectricCar的父类的方法init(),让ElectricCar实例包含父类的所有属性。父类也称为超 类(superclass),名称super因此而得名
给子类定义属性和方法
让一个类继承另一个类后,可添加区分子类和父类所需的新属性和方法。
下面来添加一个电动汽车特有的属性(电瓶),以及一个描述该属性的方法。我们将存储电 瓶容量,并编写一个打印电瓶描述的方法
#9-6 冰淇淋小店:冰淇淋小店是一种特殊的餐馆。编写一个名为 IceCreamStand 的
# 类,让它继承你为完成练习 9-1 或练习 9-4 而编写的 Restaurant 类。
# 这两个版本的 Restaurant 类都可以,挑选你更喜欢的那个即可。添加一个名为
# flavors 的属性,用于 存储一个由各种口味的冰淇淋组成的列表。编写一个显示这些冰淇淋的方法。
# 创建一个 IceCreamStand 实例,并调用这个方法。
class Restaurant():
def __init__(self,restaurant_name,cuisine_type):
self.restaurant_name = restaurant_name
self.cuisine_type = cuisine_type
self.number_served = 0
def describe_restaurant(self):
print(self.restaurant_name + ' ' + self.cuisine_type)
class IceCreamStand(Restaurant):
def __init__(self,restaurant_name,cuisine_type):
super().__init__(restaurant_name,cuisine_type)
def kouwei(self,weidao):
self.weidao = weidao
print("ni xiang yao de kou wei shi:" + str(self.weidao) )
bql = IceCreamStand('xiaowu','bingao')
bql.describe_restaurant()
bql.kouwei('\nlan mei')
#
ni xiang yao de kou wei shi:
lan mei
导入类 导入单个类
随着你不断地给类添加功能,文件可能变得很长,即便你妥善地使用了继承亦如此。为遵循 Python的总体理念,应让文件尽可能整洁。为在这方面提供帮助,Python允许你将类存储在模块 中,然后在主程序中导入所需的模块
导入单个类
例子:
car.py
"""一个可用于表示汽车的类"""
class Car():
"""一次模拟汽车的简单尝试"""
def __init__(self, make, model, year):
"""初始化描述汽车的属性"""
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0
def get_descriptive_name(self):
"""返回整洁的描述性名称"""
long_name = str(self.year) + ' ' + self.make + ' ' + self.model
return long_name.title()
def read_odometer(self):
"""打印一条消息,指出汽车的里程"""
print("This car has " + str(self.odometer_reading) + " miles on it.")
def update_odometer(self, mileage):
"""将里程表读数设置为指定的值 拒绝将里程表往回拨"""
if mileage >= self.odometer_reading:
self.odometer_reading = mileage
else:
print("You can't roll back an odometer!")
def increment_odometer(self, miles):
"""将里程表读数增加指定的量"""
self.odometer_reading += miles
my_car.py
from car import Car
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
my_new_car.odometer_reading = 23
my_new_car.read_odometer()
#
2016 Audi A4
This car has 23 miles on it.
导入多个类
from car import Car, ElectricCar
from car import *
Python 标准库
字典让你能够将信息关联起来,但它们不记录你添加键—值对的顺序。要创建字典并记录其 中的键—值对的添加顺序,可使用模块collections中的OrderedDict类。OrderedDict实例的行为 几乎与字典相同,区别只在于记录了键—值对的添加顺序
例子:
9-14 骰子 : 模块random 包含以各种方式生成随机数的函数, 其中的randint() 返回一个位于指定范围内的整数,
例如, 下面的代码返回一个1~6内的整数:
from random import randint
x = randint(1, 6)
请创建一个Die 类, 它包含一个名为sides 的属性, 该属性的默认值为6。 编写一个名为roll_die() 的方法,
它打印位于1和骰子面数之间的随机数。 创建一个6面的骰子, 再掷10次。 创建一个10面的骰子和一个20面的骰子, 并将它们都掷10次。
from random import randint
class Die():
def __init__(self):
self.sides = 6
def roll_die(self):
x = randint(1,6)
self.sides = x
print(self.sides)
def roll_die10(self):
x = randint(1, 10)
self.sides = x
print(self.sides)
def roll_die20(self):
self.sides = randint(1, 20)
print(self.sides)
die = Die()
print("----------6 sides-------------")
for i in range(10):
die.roll_die()
print("----------10 sides-------------")
for i in range(10):
die.roll_die10()
print("----------20 sides-------------")
for i in range(10):
die.roll_die20()