面向对象编程是最有效的软件编写方法之一。在面向对象编程中,你编写表示现实世界中的事物和情景的类,并基于这些类来创建对象。编写类时,你定义一大类对象都有的通用行为。基于类创建对象时,每个对象都自动具备这种通用行为,然后可根据需要赋予每个对象独特的个性。使用面向对象编程可模拟现实情景,其逼真程度达到了令你惊讶的地步。
一、创建和使用类
1.创建Dog类
根据Dog 类创建的每个实例都将存储名字和年龄。我们赋予了每条小狗蹲下(sit() )和打滚(roll_over() )的能力:
class Dog():
def __init__(self,name,age):
self.name = name
self.age = age
def sit(self):
print(self.name.title()+" is now sitting.")
def roll_over(self):
print(self.name.title()+" rolled over!")
根据约定,在Python中,首字母大写的名称指的是类。这个类定义中的括号是空的,因为我们要从空白创建这个类。
方法_init_()
类中的函数称为方法。其中_init_()是一个特殊的方法,每当你根据Dog类创建新实例时,python都会自动运行它。在这个方法中,开头和结尾都有一条下划线以避免冲突。
方法_init_()中的形参self必不可少,且必须位于首位。当Python调用这个_init_()方法来创建Dog实例时,将自动传入实参self。每个与类相关联的方法调用都自动传递实参self,它是一个指向实例本身的引用,让实例能够访问类中的属性和方法。我们创建Dog实例时,python将调用Dog类的方法_init_()。我们将通过实参向Dog()传递名字和年龄;self会自动传递,因此我们不需要传递它。每当我们根据Dog创建实例时,都只需给最后两个形参(age和name)提供值。
self.name和self.age两个变量都有前缀self,以self为前缀的变量可供类中的所有方法使用,我们还可以通过类的任何实例来访问这些变量。通过语句 self.name = name 获取存储在形参name中的值,并将其存储到变量name中,然后该变量被关联到当前创建的实例。像这样可通过实例访问的变量称为属性。
2.根据类创建实例
class Dog():
.....
.....
my_dog = Dog('milk',3)
print("My dog's name is "+my_dog.name.title()+".")
print("My dog is "+str(my_dog.age)+" years old.")
my_dog.roll_over()
输出如下:
My dog's name is Milk.
My dog is 3 years old.
Milk rolled over!
可通过句点运算符访问属性、调用方法。
动手试一试9-1 — 9-3
#9-1
print("\n9-1:\n")
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)
print(self.cuisine_type)
def open_restaurant(self):
print("The "+self.cuisine_type+" restaurant named "+self.restaurant_name+" is open.")
hanhan_restaurant = Restaurant('hanhan', 'Chinese food')
hanhan_restaurant.describe_restaurant()
hanhan_restaurant.open_restaurant()
#9-2
print("\n9-2:\n")
a_restaurant = Restaurant('a','Chinese food')
a_restaurant.describe_restaurant()
a_restaurant.open_restaurant()
#9-3
print("\n9-3:\n")
class User():
def __init__(self,first_name,last_name,sex):
self.first_name = first_name
self.last_name = last_name
self.sex = sex
def describe_user(self):
print("first name:"+self.first_name)
print("last_name:"+self.last_name)
print("sex:"+self.sex)
def greet_user(self):
print("Hello,"+self.last_name.title()+" "+self.first_name.title()+"!")
a_user = User('goudan','li','man')
a_user.describe_user()
a_user.greet_user()
输出如下:
9-1:
hanhan
Chinese food
The Chinese food restaurant named hanhan is open.
9-2:
a
Chinese food
The Chinese food restaurant named a is open.
9-3:
first name:goudan
last_name:li
sex:man
Hello,Li Goudan!
二、使用类和属性
与函数部分类似,不再赘述。
动手试一试9-4 — 9-5
#9-4
print("\n9-4:\n")
class Restaurant():
def __init__(self,restaurant_name,cuisine_type):
self.restaurant_name = restaurant_name
self.cuisine_type = cuisine_type
self.number = 0
def describe_restaurant(self):
print(self.restaurant_name)
print(self.cuisine_type)
def open_restaurant(self):
print("The "+self.cuisine_type+" restaurant named "+self.restaurant_name+" is open.")
def number_served(self):
print("This restaurant has "+str(self.number)+" people.")
def set_number_served(self, number):
self.number = number
def increase_number_served(self,num):
self.number += num
hanhan_restaurant = Restaurant('hanhan', 'Chinese food')
hanhan_restaurant.number_served()
hanhan_restaurant.number = 5
hanhan_restaurant.number_served()
hanhan_restaurant.set_number_served(10)
hanhan_restaurant.number_served()
hanhan_restaurant.increase_number_served(5)
hanhan_restaurant.number_served()
#9-5
print("\n9-5:\n")
class User():
def __init__(self,first_name,last_name,sex):
self.first_name = first_name
self.last_name = last_name
self.sex = sex
self.login_attempts = 0
def describe_user(self):
print("first name:"+self.first_name)
print("last_name:"+self.last_name)
print("sex:"+self.sex)
def greet_user(self):
print("Hello,"+self.last_name.title()+" "+self.first_name.title()+"!")
def increment_login_attempts(self):
self.login_attempts += 1
def reset_login_attempts(self):
self.login_attempts = 0
a_user = User('goudan','li','man')
print(a_user.login_attempts)
a_user.increment_login_attempts()
a_user.increment_login_attempts()
print(a_user.login_attempts)
a_user.reset_login_attempts()
print(a_user.login_attempts)
输出如下:
9-4:
This restaurant has 0 people.
This restaurant has 5 people.
This restaurant has 10 people.
This restaurant has 15 people.
9-5:
0
2
0
三、继承
编写类时,并非总是要从空白开始。如果你要编写的类是另一个现成类的特殊版本,可使用继承 。一个类继承另一个类时,它将自动获得另一个类的所有属性和方法;原有的 类称为父类,而新类称为子类。子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。
1.子类的方法_init_()
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)+" mlies 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
class ElectricCar(Car):
def __init__(self,make,model,year):
super().__init__(make,model,year)
my_telsa = ElectricCar('telsa','model s',2016)
print(my_telsa.get_descriptive_name())
上述代码创建了一个新类电动汽车,继承了类汽车的内容.
super() 是一个特殊函数,帮助Python将父类和子类关联起来。这行代码让Python调用ElectricCar 的父类的方法__init__() ,让ElectricCar 实例包含父类的所 有属性。父类也称为超类(superclass),名称super因此而得名。
2.添加特有属性
class Car():
xxx
class ElectricCar(Car):
def __init__(self,make,model,year):
super().__init__(make,model,year)
self.battery_size = 70
def describe_battery(self):
print("This car has a "+str(self.battery_size)+" -kWh battery.")
my_telsa = ElectricCar('telsa','model s',2016)
print(my_telsa.get_descriptive_name())
my_telsa.describe_battery()
3.重写父类的方法
只需在子类中定义一个方法,与想要修改的父类方法名称一致即可。
4.将实例用作属性
与继承类似。
class Car():
xxx
class Battery():
def __init__(self,battery_size=70):
self.battery_size =battery_size
def describe_battery(self):
print("This car has a "+str(self.battery_size)+" -kWh battery.")
class ElectricCar(Car):
def __init__(self,make,model,year):
super().__init__(make,model,year)
self.battery = Battery()
my_telsa = ElectricCar('telsa','model s',2016)
print(my_telsa.get_descriptive_name())
my_telsa.battery.describe_battery()
动手试一试 9-6 — 9-9
# 9-6
print("\n9-6:\n")
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)
print(self.cuisine_type)
def open_restaurant(self):
print("The "+self.cuisine_type+" restaurant named "+self.restaurant_name+" is open.")
class IceCreamStand(Restaurant):
def __init__(self,restaurant_name,cuisine_type):
super().__init__(restaurant_name,cuisine_type)
self.restaurant_name = restaurant_name
self.cuisine_type = cuisine_type
def describe_icecream(self):
flavours = ['milk','chocolate','sugar']
print("We have the following tastes:\n"+str(flavours))
ice = IceCreamStand('hanhan','Chinese')
ice.open_restaurant()
ice.describe_icecream()
# 9-7
print("\n9-7:\n")
class User():
def __init__(self,first_name,last_name,sex):
self.first_name = first_name
self.last_name = last_name
self.sex = sex
self.login_attempts = 0
def describe_user(self):
print("first name:"+self.first_name)
print("last_name:"+self.last_name)
print("sex:"+self.sex)
def greet_user(self):
print("Hello,"+self.last_name.title()+" "+self.first_name.title()+"!")
def increment_login_attempts(self):
self.login_attempts += 1
def reset_login_attempts(self):
self.login_attempts = 0
class Admin(User):
def __init__(self,first_name,last_name,sex):
super().__init__(first_name,last_name,sex)
self.first_name = first_name
self.last_name = last_name
def show_privileges(self):
string = ["can add post","can delete post","can ban user"]
print("User's power:\n"+str(string))
goudan = Admin('goudan','li','man')
goudan.show_privileges()
#9-8
print("\n9-8:\n")
class Privileges():
def __init__(self,list=["can add post","can delete post","can ban user"]):
self.list = list
def show_privileges(self):
print(self.list)
class Admin(User):
def __init__(self,first_name,last_name,sex):
super().__init__(first_name,last_name,sex)
self.first_name = first_name
self.last_name = last_name
self.privilege = Privileges()
goudandan = Admin('goudandan','li','man')
goudandan.privilege.show_privileges()
#9-9
print("\n9-9:\n")
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)+" mlies 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
class Battery():
def __init__(self,battery_size=70):
self.battery_size =battery_size
def describe_battery(self):
print("This car has a "+str(self.battery_size)+" -kWh battery.")
def get_range(self):
if self.battery_size == 70:
range = 240
elif self.battery_size ==85:
range = 270
message = "This car can go approximately "+str(range)
message += " miles on a full charge."
print(message)
def upgrade_battery(self):
if self.battery_size != 85:
self.battery_size = 85
else:
self.battery_size = self.battery_size
class ElectricCar(Car):
def __init__(self,make,model,year):
super().__init__(make,model,year)
self.battery = Battery()
xiaoniao = ElectricCar('telsa','model s',2016)
print(xiaoniao.get_descriptive_name())
xiaoniao.battery.describe_battery()
xiaoniao.battery.get_range()
xiaoniao.battery.upgrade_battery()
xiaoniao.battery.describe_battery()
xiaoniao.battery.get_range()
输出如下:
9-6:
The Chinese restaurant named hanhan is open.
We have the following tastes:
['milk', 'chocolate', 'sugar']
9-7:
User's power:
['can add post', 'can delete post', 'can ban user']
9-8:
['can add post', 'can delete post', 'can ban user']
9-9:
2016 Telsa Model S
This car has a 70 -kWh battery.
This car can go approximately 240 miles on a full charge.
This car has a 85 -kWh battery.
This car can go approximately 270 miles on a full charge.
四、导入类
同函数。
动手试一试 9-10 — 9-12
略
五、python标准库
1.collections模块中的类——OrderedDict
字典让你能够将信息关联起来,但它们不记录你添加键—值对的顺序。要创建字典并记录其中的键—值对的添加顺序,可使用模块collections 中的OrderedDict 类。OrderedDict 实例的行为几乎与字典相同,区别只在于记录了键—值对的添加顺序。
from collections import OrderedDict
favourite_languages = OrderedDict()
favourite_languages['jen'] = 'python'
favourite_languages['tom'] = 'java'
for name,language in favourite_languages.items():
print(name)
print(language)
输出如下:
jen
python
tom
java
动手试一试9-13 9-14
9-13 略
#9-14
print("\n9-14:\n")
from random import randint
class Die():
def __init__(self,sides=6):
self.sides = sides
def roll_die(self):
print(randint(1,self.sides))
dice_6 = Die()
dice_10 = Die(10)
dice_20 = Die(20)
print("The dice which has 6 sides:")
for i in range(10):
dice_6.roll_die()
print("\nThe dice which has 10 sides:")
for i in range(10):
dice_10.roll_die()
print("\nThe dice which has 20 sides:")
for i in range(10):
dice_20.roll_die()
输出如下:
9-14:
The dice which has 6 sides:
3
3
5
5
3
1
5
6
3
1
The dice which has 10 sides:
2
7
8
6
2
10
7
2
8
1
The dice which has 20 sides:
17
16
12
4
13
12
8
4
17
6