python--类


创建Dog类

根据Dog 类创建的每个实例都将存储名字和年龄。我们赋予了每条小狗蹲下(sit() )和打滚(roll_over() )的能力:

 1 class Dog():
 2     '''一次模拟小狗的简单尝试'''
 3     
 4     def __init__(self, name, age):
 5         """初始化属性name和age"""
 6         self.name = name
 7         self.age = age
 8     
 9     def sit(self):
10         """模拟小狗被命令时蹲下"""
11         print(self.name.title() + " is now sitting.")
12         
13     def roll_over(self):
14         """模拟小狗被命令时打滚"""
15         print(self.name.title() + " rolled over!")
16         

 

根据类创建实例

 1 class Dog():
 2     '''一次模拟小狗的简单尝试'''
 3 
 4     def __init__(self, name, age):
 5         """初始化属性name和age"""
 6         self.name = name
 7         self.age = age
 8 
 9     def sit(self):
10         """模拟小狗被命令时蹲下"""
11         print(self.name.title() + " is now sitting.")
12 
13     def roll_over(self):
14         """模拟小狗被命令时打滚"""
15         print(self.name.title() + " rolled over!")
16 
17 my_dog = Dog('willie', 6)
18 your_dog = Dog('lucy', 3)   # 创建多个实例
19 
20 print("My dog's name is " + my_dog.name.title() + ".")      # my_dog.name 访问属性
21 print("My dog is " + str(my_dog.age) + " years old.")
22 my_dog.sit()        # 调用方法
23 my_dog.roll_over()
24 
25 print("\nYour dog's name is " + your_dog.name.title() + ".")
26 print("Your dog is " + str(your_dog.age) + " years old.")
27 your_dog.sit()

运行结果

My dog's name is Willie.
My dog is 6 years old.
Willie is now sitting.
Willie rolled over!

Your dog's name is Lucy.
Your dog is 3 years old.
Lucy is now sitting.

Process finished with exit code 0

 

使用类和实例

Car类

 1 class Car():
 2     """一次模拟汽车的简单尝试"""
 3 
 4     def __init__(self, make, model, year):
 5         """初始化描述汽车的属性"""
 6         self.make = make
 7         self.model = model
 8         self.year = year
 9         self.odometer_reading = 0       # 给属性指定默认值
10 
11     def get_descriptive_name(self):
12         """返回整洁的描述性信息"""
13         long_name = str(self.year) + ' ' + self.make + ' ' + self.model
14         return long_name.title()
15 
16     def read_odometer(self):
17         """打印一条指出汽车里程的消息"""
18         print("This car has " + str(self.odometer_reading) + " miles on it.")
19 
20 my_new_car = Car('audi', 'a4', 2016)
21 print(my_new_car.get_descriptive_name())
22 my_new_car.read_odometer()

运行结果

2016 Audi A4
This car has 0 miles on it.

Process finished with exit code 0

修改属性的值

1、直接修改属性的值

 1 class Car():
 2     """一次模拟汽车的简单尝试"""
 3 
 4     def __init__(self, make, model, year):
 5         """初始化描述汽车的属性"""
 6         self.make = make
 7         self.model = model
 8         self.year = year
 9         self.odometer_reading = 0       # 给属性指定默认值
10 
11     def get_descriptive_name(self):
12         """返回整洁的描述性信息"""
13         long_name = str(self.year) + ' ' + self.make + ' ' + self.model
14         return long_name.title()
15 
16     def read_odometer(self):
17         """打印一条指出汽车里程的消息"""
18         print("This car has " + str(self.odometer_reading) + " miles on it.")
19 
20 my_new_car = Car('audi', 'a4', 2016)
21 print(my_new_car.get_descriptive_name())
22 my_new_car.odometer_reading = 23    # 直接修改属性的值
23 my_new_car.read_odometer()

运行结果

2016 Audi A4
This car has 23 miles on it.

Process finished with exit code 0

 

2、通过方法修改属性的值

 1 class Car():
 2     """一次模拟汽车的简单尝试"""
 3 
 4     def __init__(self, make, model, year):
 5         """初始化描述汽车的属性"""
 6         self.make = make
 7         self.model = model
 8         self.year = year
 9         self.odometer_reading = 0       # 给属性指定默认值
10 
11     def get_descriptive_name(self):
12         """返回整洁的描述性信息"""
13         long_name = str(self.year) + ' ' + self.make + ' ' + self.model
14         return long_name.title()
15 
16     def read_odometer(self):
17         """打印一条指出汽车里程的消息"""
18         print("This car has " + str(self.odometer_reading) + " miles on it.")
19 
20     def update_odometer(self, mileage):
21         """将里程表读数设置为指定的值"""
22         self.odometer_reading = mileage
23 
24 my_new_car = Car('audi', 'a4', 2016)
25 print(my_new_car.get_descriptive_name())
26 
27 my_new_car.update_odometer(23)  # 通过方法修改属性的值
28 my_new_car.read_odometer()

 

3、通过方法对属性的值进行递增

 1 class Car():
 2     """一次模拟汽车的简单尝试"""
 3 
 4     def __init__(self, make, model, year):
 5         """初始化描述汽车的属性"""
 6         self.make = make
 7         self.model = model
 8         self.year = year
 9         self.odometer_reading = 0       # 给属性指定默认值
10 
11     def get_descriptive_name(self):
12         """返回整洁的描述性信息"""
13         long_name = str(self.year) + ' ' + self.make + ' ' + self.model
14         return long_name.title()
15 
16     def read_odometer(self):
17         """打印一条指出汽车里程的消息"""
18         print("This car has " + str(self.odometer_reading) + " miles on it.")
19 
20     def update_odometer(self, mileage):
21         """将里程表读数设置为指定的值
22         禁止将里程表读数往回调
23         """
24         if mileage >= self.odometer_reading:
25             self.odometer_reading = mileage
26         else:
27             print("You can't roll back an odometer!")
28 
29     def increment_odometer(self, miles):
30         """将里程表读数增加指定的量"""
31         self.odometer_reading += miles
32 
33 my_used_car = Car('subaru', 'outback', 2013)
34 print(my_used_car.get_descriptive_name())
35 
36 my_used_car.update_odometer(23500)
37 my_used_car.read_odometer()
38 
39 my_used_car.update_odometer(100)
40 my_used_car.read_odometer()
41 
42 my_used_car.increment_odometer(100)     # 通过方法对属性的值进行递增
43 my_used_car.read_odometer()

运行结果

2013 Subaru Outback
This car has 23500 miles on it.
You can't roll back an odometer!
This car has 23500 miles on it.
This car has 23600 miles on it.

Process finished with exit code 0

 

继承

给子类定义属性和方法

 1 class Car():
 2     """一次模拟汽车的简单尝试"""
 3 
 4     def __init__(self, make, model, year):
 5         """初始化描述汽车的属性"""
 6         self.make = make
 7         self.model = model
 8         self.year = year
 9         self.odometer_reading = 0       # 给属性指定默认值
10 
11     def get_descriptive_name(self):
12         """返回整洁的描述性信息"""
13         long_name = str(self.year) + ' ' + self.make + ' ' + self.model
14         return long_name.title()
15 
16     def read_odometer(self):
17         """打印一条指出汽车里程的消息"""
18         print("This car has " + str(self.odometer_reading) + " miles on it.")
19 
20     def update_odometer(self, mileage):
21         """将里程表读数设置为指定的值
22         禁止将里程表读数往回调
23         """
24         if mileage >= self.odometer_reading:
25             self.odometer_reading = mileage
26         else:
27             print("You can't roll back an odometer!")
28 
29     def increment_odometer(self, miles):
30         """将里程表读数增加指定的量"""
31         self.odometer_reading += miles
32 
33 class ElectricCar(Car):
34     """电动车的独特之处"""
35 
36     def __init__(self, make, model, year):
37         """
38         电动汽车的独特之处
39         初始化父类的属性,再初始化电动汽车特有的属性
40         """
41         super().__init__(make, model, year)
42         self.battery_size = 70
43 
44     def describe_battery(self):
45         """打印一条描述电瓶容量的消息"""
46         print("This car has a " + str(self.battery_size) + "-kWh battery.")
47 
48 my_tesla = ElectricCar('tesla', 'model s', 2016)
49 print(my_tesla.get_descriptive_name())
50 my_tesla.describe_battery()

super() 是一个特殊函数,帮助Python将父类和子类关联起来。这行代码让Python调用ElectricCar的父类的方法__init__(),让ElectricCar实例包含父类的所有属性。父类也称为超类(superclass),名称super因此而得名。

 

运行结果

2016 Tesla Model S
This car has a 70-kWh battery.

Process finished with exit code 0

 

重写父类的方法

对于父类的方法,只要它不符合子类模拟的实物的行为,都可对其进行重写。为此,可在子类中定义一个这样的方法,即它与要重写的父类方法同名。这样,Python将不会考虑这 个父类方法,而只关注你在子类中定义的相应方法。 假设Car 类有一个名为fill_gas_tank() 的方法,它对全电动汽车来说毫无意义,因此你可能想重写它。下面演示了一种重写方式:

def ElectricCar(Car):
    --snip--
    def fill_gas_tank():
        """电动汽车没有油箱"""
        print("This car doesn't need a gas tank!")

现在,如果有人对电动汽车调用方法fill_gas_tank() ,Python将忽略Car 类中的方法fill_gas_tank() ,转而运行上述代码。使用继承时,可让子类保留从父类那里继 承而来的精华,并剔除不需要的糟粕。

 

将实例用作属性

使用代码模拟实物时,你可能会发现自己给类添加的细节越来越多:属性和方法清单以及文件都越来越长。在这种情况下,可能需要将类的一部分作为一个独立的类提取出来。 你可以将大型类拆分成多个协同工作的小类。

 1 class Car():
 2     """一次模拟汽车的简单尝试"""
 3 
 4     def __init__(self, make, model, year):
 5         """初始化描述汽车的属性"""
 6         self.make = make
 7         self.model = model
 8         self.year = year
 9         self.odometer_reading = 0       # 给属性指定默认值
10 
11     def get_descriptive_name(self):
12         """返回整洁的描述性信息"""
13         long_name = str(self.year) + ' ' + self.make + ' ' + self.model
14         return long_name.title()
15 
16     def read_odometer(self):
17         """打印一条指出汽车里程的消息"""
18         print("This car has " + str(self.odometer_reading) + " miles on it.")
19 
20     def update_odometer(self, mileage):
21         """将里程表读数设置为指定的值
22         禁止将里程表读数往回调
23         """
24         if mileage >= self.odometer_reading:
25             self.odometer_reading = mileage
26         else:
27             print("You can't roll back an odometer!")
28 
29     def increment_odometer(self, miles):
30         """将里程表读数增加指定的量"""
31         self.odometer_reading += miles
32 
33 class Battery():
34     """一次模拟电动汽车电瓶的简单尝试"""
35     def __init__(self, battery_size = 70):
36         """初始化电瓶的属性"""
37         self.battery_size = battery_size
38 
39     def describe_battery(self):
40         """打印一条描述电瓶容量的消息"""
41         print("This car has a " + str(self.battery_size) + "-kWh battery.")
42 
43 class ElectricCar(Car):
44     """电动车的独特之处"""
45 
46     def __init__(self, make, model, year):
47         """
48         电动汽车的独特之处
49         初始化父类的属性,再初始化电动汽车特有的属性
50         """
51         super().__init__(make, model, year)
52         self.battery = Battery()
53 
54 my_tesla = ElectricCar('tesla', 'model s', 2016)
55 print(my_tesla.get_descriptive_name())
56 my_tesla.battery.describe_battery()

下面再给Battery 类添加一个方法,它根据电瓶容量报告汽车 的续航里程:

 1 class Car():
 2     """一次模拟汽车的简单尝试"""
 3 
 4     def __init__(self, make, model, year):
 5         """初始化描述汽车的属性"""
 6         self.make = make
 7         self.model = model
 8         self.year = year
 9         self.odometer_reading = 0       # 给属性指定默认值
10 
11     def get_descriptive_name(self):
12         """返回整洁的描述性信息"""
13         long_name = str(self.year) + ' ' + self.make + ' ' + self.model
14         return long_name.title()
15 
16     def read_odometer(self):
17         """打印一条指出汽车里程的消息"""
18         print("This car has " + str(self.odometer_reading) + " miles on it.")
19 
20     def update_odometer(self, mileage):
21         """将里程表读数设置为指定的值
22         禁止将里程表读数往回调
23         """
24         if mileage >= self.odometer_reading:
25             self.odometer_reading = mileage
26         else:
27             print("You can't roll back an odometer!")
28 
29     def increment_odometer(self, miles):
30         """将里程表读数增加指定的量"""
31         self.odometer_reading += miles
32 
33 class Battery():
34     """一次模拟电动汽车电瓶的简单尝试"""
35     def __init__(self, battery_size = 70):
36         """初始化电瓶的属性"""
37         self.battery_size = battery_size
38 
39     def describe_battery(self):
40         """打印一条描述电瓶容量的消息"""
41         print("This car has a " + str(self.battery_size) + "-kWh battery.")
42 
43     def get_range(self):
44         """打印一条消息,指出电瓶的续航里程"""
45         if self.battery_size == 70:
46             range = 240
47         elif self.battery_size == 85:
48             range = 270
49 
50         message = "This car can go approximately " + str(range)
51         message += " miles on a full charge."
52         print(message)
53 
54 
55 class ElectricCar(Car):
56     """电动车的独特之处"""
57 
58     def __init__(self, make, model, year):
59         """
60         电动汽车的独特之处
61         初始化父类的属性,再初始化电动汽车特有的属性
62         """
63         super().__init__(make, model, year)
64         self.battery = Battery()
65 
66 my_tesla = ElectricCar('tesla', 'model s', 2016)
67 print(my_tesla.get_descriptive_name())
68 my_tesla.battery.describe_battery()
69 my_tesla.battery.get_range()

运行结果

2016 Tesla Model S
This car has a 70-kWh battery.
This car can go approximately 240 miles on a full charge.

Process finished with exit code 0

 

模拟实物

模拟较复杂的物件(如电动汽车)时,需要解决一些有趣的问题。续航里程是电瓶的属性还是汽车的属性呢?如果我们只需描述一辆汽车,那么将方法get_range() 放 在Battery 类中也许是合适的;但如果要描述一家汽车制造商的整个产品线,也许应该将方法get_range() 移到ElectricCar 类中。在这种情况下,get_range() 依然 根据电瓶容量来确定续航里程,但报告的是一款汽车的续航里程。我们也可以这样做:将方法get_range() 还留在Battery 类中,但向它传递一个参数,如car_model ;在 这种情况下,方法get_range() 将根据电瓶容量和汽车型号报告续航里程。 这让你进入了程序员的另一个境界:解决上述问题时,你从较高的逻辑层面(而不是语法层面)考虑;你考虑的不是Python,而是如何使用代码来表示实物。到达这种境界后,你 经常会发现,现实世界的建模方法并没有对错之分。有些方法的效率更高,但要找出效率最高的表示法,需要经过一定的实践。只要代码像你希望的那样运行,就说明你做得很 好!即便你发现自己不得不多次尝试使用不同的方法来重写类,也不必气馁;要编写出高效、准确的代码,都得经过这样的过程。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM