Python编程:从入门到实践——第9章、类(附课后题)

9.1 创建和使用类

#9.1.1 创建Dog 类
class Dog():
    """一次模拟小狗的简单尝试"""
    def __init__(self,name,age):
        """初始化属性name 和 age"""
        self.name = name
        self.age = age

    def sit(self):
        """模拟小狗被命令是蹲下"""
        print(self.name.title() + " is now siting.")

    def roll_over(self):
        """模拟小狗被命令时打滚"""
        print(self.name.title() + " rolled 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.roll_over()
#这里使用的是前一个示例中编写的Dog 类。我们让Python创建一条名字为'willie' 、年龄为6 的小狗。遇到这行代码时,Python使用实参'willie' 和调用Dog 类
#中的方法__init__() 。方法__init__() 创建一个表示特定小狗的示例,并使用我们提供的值来设置属性name 和age 。方法__init__() 并未显式地包含return 语句,
#但Python自动返回一个表示这条小狗的实例。我们将这个实例存储在变量my_dog 中。在这里,命名约定很有用:我们通常可以认为首字母大写的名称(如Dog )指的是类,而
#小写的名称(如my_dog )指的是根据类创建的实例。

#类约定首字母大写
#1. 方法__init__()
#类中的函数称为方法 ;你前面学到的有关函数的一切都适用于方法,就目前而言,唯一重要的差别是调用方法的方式。方法__init__() 是一个特殊的方法,每当你根
#据Dog 类创建新实例时,Python都会自动运行它。在这个方法的名称中,开头和末尾各有两个下划线,这是一种约定,旨在避免Python默认方法与普通方法发生名称冲突。
#我们将方法__init__() 定义成了包含三个形参:self 、name 和age 。在这个方法的定义中,形参self 必不可少,还必须位于其他形参的前面。为何必须在方法定义中包
#含形参self 呢?因为Python调用这个__init__() 方法来创建Dog 实例时,将自动传入实参self 。每个与类相关联的方法调用都自动传递实参self ,它是一个指向实例本身
#的引用,让实例能够访问类中的属性和方法。我们创建Dog 实例时,Python将调用Dog 类的方法__init__() 。我们将通过实参向Dog() 传递名字和年龄;self 会自动传递,
#因此我们不需要传递它。每当我们根据Dog 类创建实例时,都只需给最后两个形参(name 和age )提供值

#定义的两个变量都有前缀self 。以self 为前缀的变量都可供类中的所有方法使用,我们还可以通过类的任何实例来访问这些变量。self.name = name 获取存储在形
#参name 中的值,并将其存储到变量name 中,然后该变量被关联到当前创建的实例。self.age = age 的作用与此类似。像这样可通过实例访问的变量称为属性

属性访问

通过实例化后的类名.方法访问
python先找到实例my_dog,在查找关联的属性my_dog.name ,在Dog类中引用这个属性时,使用的是self.name,即应用传入的name值。

9.2 使用类和实例

#直接修改实例属性或编写特定方法修改属性
class Car():
    """一次模拟汽车的简单尝试"""
    def __init__(self,make,model,year):
        """初始化描述汽车的属性,设定了3个形参,在根据该类创建实例时,需要指定实例属性"""
        self.make = make
        self.model = model
        self.year = year
    def get_descriptive_name(self):
        """返回整洁的描述信息,使用属性创建一个汽车的描述字符串,根据创建的实例,将其存储在变量实例中"""
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()
my_new_car = Car('audi','a4',2016)
print(my_new_car.get_descriptive_name())

9.2.2 给属性指定默认值

class Car():
    """一次模拟汽车的简单尝试"""
    def __init__(self,make,model,year):
        """初始化描述汽车的属性,设定了3个形参,在根据该类创建实例时,需要指定实例属性"""
        self.make = make
        self.model = model
        self.year = year
        #增加一个里程属性,默认值为0,这样做为了无需包含为他提供初始值的形参
        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.")
my_new_car = Car('audi','a4',2016)
print(my_new_car.get_descriptive_name())
my_new_car.read_odometer()

9.2.3 修改属性的值

#出售时,里程表为0的汽车并不多,因此需要提供修改属性值得途径代码
class Car():
    """一次模拟汽车的简单尝试"""
    def __init__(self,make,model,year):
        """初始化描述汽车的属性,设定了3个形参,在根据该类创建实例时,需要指定实例属性"""
        self.make = make
        self.model = model
        self.year = year
        #增加一个里程属性,默认值为0,这样做为了无需包含为他提供初始值的形参
        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):
        """将里程读数设置为指定的数,禁止将里程数回调,即原本已打印行驶10,之后修改小于10"""
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("You can't roll back an odometer!")
        # self.odometer_reading = mileage
my_new_car = Car('audi','a4',2016)
print(my_new_car.get_descriptive_name())
#最简单修改属性方法,直接通过实例访问修改属性
my_new_car.odometer_reading = 23
#通过update_odometer方法修改属性值
my_new_car.update_odometer(30)
my_new_car.read_odometer()

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

#有市需要将属性值递增特定的量,例如购买2手车,且购买到登记期间行使100KM
class Car():
    """一次模拟汽车的简单尝试"""
    def __init__(self,make,model,year):
        """初始化描述汽车的属性,设定了3个形参,在根据该类创建实例时,需要指定实例属性"""
        self.make = make
        self.model = model
        self.year = year
        #增加一个里程属性,默认值为0,这样做为了无需包含为他提供初始值的形参
        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):
        """将里程读数设置为指定的数,禁止将里程数回调,即原本已打印行驶10,之后修改小于10"""
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("You can't roll back an odometer!")
        # self.odometer_reading = mileage
    def increment_odometer(self,miles):
        """将里程表读数增加特定的量"""
        self.odometer_reading += miles
my_new_car = Car('audi','a4',2016)
print(my_new_car.get_descriptive_name())
#最简单修改属性方法,直接通过实例访问修改属性
my_new_car.odometer_reading = 23
#通过update_odometer方法修改属性值
my_new_car.update_odometer(30)
my_new_car.increment_odometer(100)
my_new_car.read_odometer()

9.3 继承

#一个类继承 另一个类时,它将自动获得另一个类的所有属性和方法;原有的
#类称为父类 ,而新类称为子类 。子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。
class Car():
    """一次模拟汽车的简单尝试"""
    def __init__(self,make,model,year):
        """初始化描述汽车的属性,设定了3个形参,在根据该类创建实例时,需要指定实例属性"""
        self.make = make
        self.model = model
        self.year = year
    def get_descriptive_name(self):
        """返回整洁的描述信息,使用属性创建一个汽车的描述字符串,根据创建的实例,将其存储在变量实例中"""
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()

    """
    1.子类与父类需在一个文件夹内,且位于父类之后
    2.子类括号内需填写继承的父类名称
    """
class ElectrioCar(Car):
    """电动车的独特之处"""
    """
    1.方法__init__(),接受创建Car实例所需的信息
    """
    def __init__(self,make,model,year):
        """初始化父类"""
        """
        1.super()方法是一个特殊方法,将父类与子类联系起来,这行代码能让python调用子类ElectrioCar的父类方法__init__(),
        让子类ElectrioCar实例包含父类所有属性,父类也成为超类(superclass)
        """
        super().__init__(make,model,year)
my_tesla = ElectrioCar('telsa','models',2016)
print(my_tesla.get_descriptive_name())

9.3.3 给子类定义属性和方法

#继承父类后,为子类添加自己的属性和方法,例如添加电瓶车的电瓶,以及描述电瓶电量
class Car():
    """一次模拟汽车的简单尝试"""
    def __init__(self,make,model,year):
        """初始化描述汽车的属性,设定了3个形参,在根据该类创建实例时,需要指定实例属性"""
        self.make = make
        self.model = model
        self.year = year
    def get_descriptive_name(self):
        """返回整洁的描述信息,使用属性创建一个汽车的描述字符串,根据创建的实例,将其存储在变量实例中"""
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()

    """
    1.子类与父类需在一个文件夹内,且位于父类之后
    2.子类括号内需填写继承的父类名称
    """
class ElectrioCar(Car):
    """电动车的独特之处"""
    """
    1.方法__init__(),接受创建Car实例所需的信息
    """
    def __init__(self,make,model,year):
        """初始化父类"""
        """
        1.super()方法是一个特殊方法,将父类与子类联系起来,这行代码能让python调用子类ElectrioCar的父类方法__init__(),
        让子类ElectrioCar实例包含父类所有属性,父类也成为超类(superclass)
        """
        super().__init__(make,model,year)
        """
        1.初始化父类后,可定义子类特有属性
        """
        self.battery_size = 70

    def describe_battery(self):
        """打印电瓶电量信息"""
        print("This ElectrioCar has a " + str(self.battery_size) + "-KWh battary.")
my_tesla = ElectrioCar('telsa','models',2016)
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()

9.3.4 重写父类的方法

#父类不符合子类的属性和行为动作,可对其重写,即它要重写的方法与父类方法同名,这样,python不会考虑这个父类方法,只关注子类方法
class Car():
    """一次模拟汽车的简单尝试"""
    def __init__(self,make,model,year):
        """初始化描述汽车的属性,设定了3个形参,在根据该类创建实例时,需要指定实例属性"""
        self.make = make
        self.model = model
        self.year = year
    def get_descriptive_name(self):
        """返回整洁的描述信息,使用属性创建一个汽车的描述字符串,根据创建的实例,将其存储在变量实例中"""
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()
    def fill_gas_tank(self):
        """父类中有邮箱的方法"""
        print("This Car need a gas tak!")


    """
    1.子类与父类需在一个文件夹内,且位于父类之后
    2.子类括号内需填写继承的父类名称
    """
class ElectrioCar(Car):
    """电动车的独特之处"""
    """
    1.方法__init__(),接受创建Car实例所需的信息
    """
    def __init__(self,make,model,year):
        """初始化父类"""
        """
        1.super()方法是一个特殊方法,将父类与子类联系起来,这行代码能让python调用子类ElectrioCar的父类方法__init__(),
        让子类ElectrioCar实例包含父类所有属性,父类也成为超类(superclass)
        """
        super().__init__(make,model,year)
        """
        1.初始化父类后,可定义子类特有属性
        """
        self.battery_size = 70

    def describe_battery(self):
        """打印电瓶电量信息"""
        print("This ElectrioCar has a " + str(self.battery_size) + "-KWh battary.")

    def fill_gas_tank(self):
        """全电动的汽车不需要油箱,因此需要重写父类油箱方法"""
        print("This ElectrioCar doesn't need a gas tank!")
my_tesla = ElectrioCar('telsa','models',2016)
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()
my_tesla.fill_gas_tank()#调用子类重写的方法
my_car = Car('BMW','Big',2018)
my_car.fill_gas_tank()#调用父类方法

9.3.5 将实例用作属性

#随着类中属性和方法描述的细节越来越多,最好的方法是可以将一部分作为单独类提取出来,成为一个个协同合作的小类。
class Car():
    """一次模拟汽车的简单尝试"""
    def __init__(self,make,model,year):
        """初始化描述汽车的属性,设定了3个形参,在根据该类创建实例时,需要指定实例属性"""
        self.make = make
        self.model = model
        self.year = year
    def get_descriptive_name(self):
        """返回整洁的描述信息,使用属性创建一个汽车的描述字符串,根据创建的实例,将其存储在变量实例中"""
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()
    def fill_gas_tank(self):
        """父类中有邮箱的方法"""
        print("This Car need a gas tak!")
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 ElectrioCar(Car):
    """
    1.子类与父类需在一个文件夹内,且位于父类之后
    2.子类括号内需填写继承的父类名称
    """

    def __init__(self,make,model,year):
        """初始化父类"""
        """电动车的独特之处"""
        """
        1.方法__init__(),接受创建Car实例所需的信息
        """
        super().__init__(make,model,year)
        """
        1.super()方法是一个特殊方法,将父类与子类联系起来,这行代码能让python调用子类ElectrioCar的父类方法__init__(),
        让子类ElectrioCar实例包含父类所有属性,父类也成为超类(superclass)
         """
        """调用Battery类中的方法"""
        self.battery = Battery()#将自动创建的实例对象Battery存储在battery中,在ElectrioCar一初始化即已实例化Battery类中属性,获取默认值70

    def fill_gas_tank(self):
        """全电动的汽车不需要油箱,因此需要重写父类油箱方法"""
        print("This ElectrioCar doesn't need a gas tank!")
my_tesla = ElectrioCar('telsa','models',2016)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()
my_tesla.fill_gas_tank()#调用子类重写的方法
my_car = Car('BMW','Big',2018)
my_car.fill_gas_tank()#调用父类方法

9.4 导入类

#9.4.1 导入单个类
#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
    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()

9.4.2 

在一个模块中存储多个类

#虽然同一个模块中的类之间应存在某种相关性,但可根据需要在一个模块中存储任意数量的类。类Battery 和ElectricCar 都可帮助模拟汽车,因此下面将它们都加入模块
class Car():
    """一次模拟汽车的简单尝试"""
    def __init__(self,make,model,year):
        """初始化描述汽车的属性,设定了3个形参,在根据该类创建实例时,需要指定实例属性"""
        self.make = make
        self.model = model
        self.year = year
        #增加一个里程属性,默认值为0,这样做为了无需包含为他提供初始值的形参
        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):
        """将里程读数设置为指定的数,禁止将里程数回调,即原本已打印行驶10,之后修改小于10"""
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("You can't roll back an odometer!")
        # self.odometer_reading = mileage
class Battery():
    """一次模拟电动汽车电瓶的简单尝试"""
    def __init__(self,battery_size = 60):
        """初始化电瓶的属性"""
        self.battery_size = battery_size
    def describe_battery(self):
        """打印一条描述电瓶容量的消息"""
        print("This car has a " + str(self.battery_size) + "-KWh battary.")
    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)
class ElectricCar(Car):
    """模拟电动汽车的独特之处"""
    def __init__(self,make,model,year):
        """初始化父类的属性,在初始化电动车特有属性"""
        super().__init__(make,model,year)
        self.battery = Battery()
#现在,可以新建一个名为my_electric_car.py的文件,导入ElectricCar 类,并创建一辆电动汽车了:
#my_electric_car.py
from car import ElectricCar

my_tesla = ElectricCar('tesla','model s',2016)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()
my_tesla.battery.get_range()

9.4.3 

从一个模块中导入多个类

#my_cars.py
from car import Car,ElectricCar
my_bettle = Car('volkswagen','bettle',2016)
print(my_bettle.get_descriptive_name())
my_tesla = ElectricCar('tesla','roadster',2016)
print(my_tesla.get_descriptive_name())

9.4.4 

导入整个模块

import car

9.4.5 

导入模块中的所有类

from module_name import 

9.4.6 

在一个模块中导入另一个模块

#一个类比较大,会分散到多个模块,例如车类,会分为汽车、电动车等
# electric_car.py
from car import Car
class Battery():
    --snip--
class ElectricCar(Car):
    --snip--
# car.py
"""一个用于表示汽车的类"""
class Car():
    --snip--
# my_cars.py
from car import  Car
from electric_car import ElectricCar

9.5 

Python标准库

from collections import OrderedDict
#字典按照添加顺序排序
favorite_languages = OrderedDict()
favorite_languages['jen'] = 'python'
favorite_languages['sarah'] = 'c'
favorite_languages['edward'] = 'ruby'
favorite_languages['phil'] = 'python'
for name,language in favorite_languages.items():
    print(name.title() + "'s favorite language is " + language.title() + '.')

练习题

#9-1
#餐馆 :创建一个名为Restaurant 的类,其方法__init__() 设置两个属性:restaurant_name 和cuisine_type 。创建一个名
#为describe_restaurant() 的方法和一个名为open_restaurant() 的方法,其中前者打印前述两项信息,而后者打印一条消息,指出餐馆正在营业。
class Restaurant():
    """餐馆类,定义餐馆两个属性:
    restaurant_name
    cuisine_type
    """
    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("餐厅正在营业!欢迎就餐")

#实例化类,调用方法
restaurant = Restaurant("川味坊","川菜")
restaurant.describe_restaurant()
restaurant.open_restaurant()
#9-2
#三家餐馆 :根据你为完成练习9-1而编写的类创建三个实例,并对每个实例调用方法describe_restaurant() 。
class Restaurant():
    """餐馆类,定义餐馆两个属性:
    restaurant_name
    cuisine_type
    """
    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 + "\n")

    def open_restaurant(self):
        print("餐厅正在营业!欢迎就餐")

#实例化类,调用方法
restaurant = Restaurant("川味坊","川菜")
restaurant_two = Restaurant("鲁家菜","鲁菜")
restaurant_tre = Restaurant("闽阁","闽菜")
restaurant.describe_restaurant()
restaurant_two.describe_restaurant()
restaurant_tre.describe_restaurant()
#9-3
#用户 :创建一个名为User 的类,其中包含属性first_name 和last_name ,还有用户简介通常会存储的其他几个属性(job,address等)。在类User 中定义一个名
#为describe_user() 的方法,它打印用户信息摘要;再定义一个名为greet_user() 的方法,它向用户发出个性化的问候
class User():
    """
    类名:User
    属性:1.first_name  2.last_name 3.用户简介通常会存储的其他几个属性
    方法:1.describe_user() 打印用户信息摘要 2.greet_user()向用户发出个性化的问候
    """
    def __init__(self,first_name,last_name,**selfintros):
        self.first_name = first_name
        self.last_name = last_name
        self.selfintros = selfintros

    def describe_user(self):
        print("用户姓名:" + self.first_name + self.last_name)
        for key,value in self.selfintros.items():
            print(key + ":" + value)
        print("\n")
    def greet_user(self):
        print("你好!" + self.first_name + self.last_name)


user_one = User('张','三',job = '销售')
user_two = User('李','四',job = '销售',address = '北京')
user_one.greet_user()
user_one.describe_user()
user_two.greet_user()
user_two.describe_user()
#9-4
#就餐人数 :在为完成练习9-1而编写的程序中,添加一个名为number_served 的属性,并将其默认值设置为0。根据这个类创建一个名为restaurant 的实
#例;打印有多少人在这家餐馆就餐过,然后修改这个值并再次打印它。
class Restaurant():
    """餐馆类,定义餐馆两个属性:
    restaurant_name
    cuisine_type
    """
    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)
        print("主打菜系:" + self.cuisine_type)

    def open_restaurant(self):
        print("餐厅正在营业!欢迎就餐")
        print("目前已经有" + str(self.number_served) + '人就餐!')

#实例化类,调用方法
restaurant = Restaurant("川味坊","川菜")
restaurant.number_served = 100
restaurant.describe_restaurant()
restaurant.open_restaurant()
#9-5
#尝试登录次数 :在为完成练习9-3而编写的User 类中,添加一个名为login_attempts 的属性。编写一个名为increment_login_attempts() 的方法,
#它将属性login_attempts 的值加1。再编写一个名为reset_login_attempts() 的方法,它将属性login_attempts 的值重置为0。
#根据User 类创建一个实例,再调用方法increment_login_attempts() 多次。打印属性login_attempts 的值,确认它被正确地递增;然后,调用方
#法reset_login_attempts() ,并再次打印属性login_attempts 的值,确认它被重置为0。
class User():
    """
    类名:User
    属性:1.first_name  2.last_name 3.用户简介通常会存储的其他几个属性
    方法:1.describe_user() 打印用户信息摘要 2.greet_user()向用户发出个性化的问候
    """
    def __init__(self,first_name,last_name,**selfintros):
        self.first_name = first_name
        self.last_name = last_name
        self.selfintros = selfintros
        self.login_attempts = 0

    def describe_user(self):
        print("用户姓名:" + self.first_name + self.last_name)
        for key,value in self.selfintros.items():
            print(key + ":" + value)
        print("\n")
    def greet_user(self):
        print("你好!" + self.first_name + self.last_name)

    def increment_login_attempts(self,nums):
        while nums > 0:
            self.login_attempts += 1
            nums -= 1

    def reset_login_attempts(self):
        self.login_attempts = 0
    def print_login_attempts(self):
        print("login_attempts值:" + str(self.login_attempts))

user_one = User('张','三',job = '销售')
user_one.increment_login_attempts(100)
user_one.print_login_attempts()
user_one.reset_login_attempts()
user_one.print_login_attempts()
#9-6
#冰淇淋小店 :冰淇淋小店是一种特殊的餐馆。编写一个名为IceCreamStand 的类,让它继承你为完成练习9-1或练习9-4而编写的Restaurant 类。这两个版
#本的Restaurant 类都可以,挑选你更喜欢的那个即可。添加一个名为flavors 的属性,用于存储一个由各种口味的冰淇淋组成的列表。编写一个显示这些冰淇淋
#的方法。创建一个IceCreamStand 实例,并调用这个方法。
class Restaurant():
    """餐馆类,定义餐馆两个属性:
    restaurant_name
    cuisine_type
    """
    def __init__(self,restaurant_name,cuisine_type):
        self.restaurant_name = restaurant_name
        self.cuisine_type = cuisine_type

    def describe_restaurant(self):
        print('店名:\n' + self.restaurant_name)
        print('主营范围:\n' + self.cuisine_type)

    def open_restaurant(self):
        print("餐厅正在营业!欢迎就餐")

class IceCreamStand(Restaurant):
    def __init__(self,restaurant_name,cuisine_type,flavors):
        super().__init__(restaurant_name,cuisine_type)
        self.flavors = flavors

    def show_icecream(self):
        print("\n在售冰激凌口味:")
        for flavor in self.flavors:
            print(flavor)
icecreamstand = IceCreamStand('甜蜜蜜冰淇淋店','甜筒系列',['香草味','草莓味','巧克力味'])
icecreamstand.describe_restaurant()
icecreamstand.show_icecream()
#9-7
#管理员 :管理员是一种特殊的用户。编写一个名为Admin 的类,让它继承你为完成练习9-3或练习9-5而编写的User 类。添加一个名为privileges 的属性,用
#于存储一个由字符串(如"can add post" 、"can delete post" 、"can ban user" 等)组成的列表。编写一个名为show_privileges() 的方法,它
#显示管理员的权限。创建一个Admin 实例,并调用这个方法。
class User():
    def __init__(self,first_name,last_name,**selfintros):
        self.first_name = first_name
        self.last_name = last_name
        self.selfintros = selfintros

    def describe_user(self):
        print("用户姓名:" + self.first_name + self.last_name)
        for key,value in self.selfintros.items():
            print(key + ":" + value)
    def greet_user(self):
        print("你好!" + self.first_name + self.last_name)

class Admin(User):
    def __init__(self,first_name,last_name,*privileges,**selfintros):
        super().__init__(first_name,last_name,**selfintros)
        self.privileges = privileges

    def show_privileges(self):
        print("管理员权限:" )
        for privilege in self.privileges:
            print(privilege)
admin = Admin('王','五','can add post','can delete post','can ban user',sex = '男',address = '北京')
admin.greet_user()
admin.describe_user()
admin.show_privileges()
#9-8
#权限 :编写一个名为Privileges 的类,它只有一个属性——privileges ,其中存储了练习9-7 所说的字符串列表。将方法show_privileges() 移到这
#个类中。在Admin 类中,将一个Privileges 实例用作其属性。创建一个Admin 实例,并使用方法show_privileges() 来显示其权限。
# !/iser/bin/env python
# coding:utf-8
class User(object):
    def __init__(self, first_name, last_name, age, phone_number):
        self.first_name = first_name
        self.last_name = last_name
        self.age = age
        self.phone_number = phone_number

    def describe_user(self):
        full_name = self.first_name + " " + self.last_name
        print(full_name + " is " + str(
            user_one.age) + " years old,and he's phone number is " + user_one.phone_number + ".")

    def greet_user(self):
        full_name = self.first_name + " " + self.last_name
        print("Hello," + full_name + " !")


class Admin(User):
    def __init__(self, first_name, last_name, age, phone_number):
        super(Admin, self).__init__(first_name, last_name, age, phone_number)
        self.privileges = Priviliges()


class Priviliges():
    def __init__(self):
        self.privileges = ["can add post", "can delete post", "can ban user"]

    def show_privileges(self):
        print("The power of admin are:")
        for privilege in self.privileges:
            print(privilege)


user_one = User('Jackson', 'Yee', 18, '1234567890')
user_one.describe_user()
user_one.greet_user()

admin = Admin('Jackson', 'Yee', 18, '1234567890')
admin.privileges.show_privileges()
#9-9
# 电瓶升级 :在本节最后一个electric_car.py版本中,给Battery 类添加一个名为upgrade_battery() 的方法。这个方法检查电瓶容量,如果它不是85,就将它
#设置为85。创建一辆电瓶容量为默认值的电动汽车,调用方法get_range() ,然后对电瓶进行升级,并再次调用get_range() 。你会看到这辆汽车的续航里程增
#加了。
class Car(object):
    def __init__(self,make,model,year):
        """初始化描述汽车的属性"""
        self.make=make
        self.model=model
        self.year=year
        self.odometer_reading=0
        self.miles=0
    def get_desprective_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
            #将里程值存储在odometer_reading中
        else:
            print("You can't roll back an odometer!")
    def increment_odometer(self,miles):
        """将里程表读数增加指定的量"""
        if miles>=self.miles:
            self.odometer_reading+=miles
        else:
            print("You can't add the miles which is negative number!")
    def fill_gas_tank(self):
        print("This car have a  gas tank")
class Battery():
    """一次模拟电动汽车电瓶的简单尝试"""
    def __init__(self,battery_size=70):
        #battery_size为形参
        """初始化电瓶的属性"""
        self.battery_size=battery_size
    def describe_battery(self):
        """打印一条描述电瓶容量的信息"""
        print("This car has a "+str(self.battery_size)+"-kwh battery.")
        #方法describe_battery被移到了Barrery类中
    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
class ElectricCar(Car):
    def __init__(self,make,model,age):
        super(ElectricCar,self).__init__(make,model,age)
        self.battery=Battery()
        #创建一个新的Battery实例,并将这个实力存储在属性self.battery中
    def fill_gas_tank(self):
        print("This car doesn't have a gas tank!")
        #对父类方法进行重写
my_elsctic=ElectricCar('tesla','model s','2016')
print(my_elsctic.get_desprective_name())
my_elsctic.battery.describe_battery()
my_elsctic.battery.get_range()
my_elsctic.battery.upgrade_battery()
my_elsctic.battery.get_range()
my_elsctic.fill_gas_tank()
# 9-10
# 导入Restaurant 类 :将最新的Restaurant 类存储在一个模块中。在另一个文件中,导入Restaurant 类,创建一个Restaurant 实例,并调
# 用Restaurant 的一个方法,以确认import 语句正确无误。
#res.py
class Restaurant():
    """餐馆类,定义餐馆两个属性:
    restaurant_name
    cuisine_type
    """
    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("餐厅正在营业!欢迎就餐")
#my_res,py
from res import Restaurant
my_res = Restaurant('川味坊','川菜')
my_res.describe_restaurant()
# 9-11
# 导入Admin 类 :以为完成练习9-8而做的工作为基础,将User 、Privileges 和Admin 类存储在一个模块中,再创建一个文件,在其中创建一个Admin 实例
# 并对其调用方法show_privileges() ,以确认一切都能正确地运行。
#user.py
class User(object):
    def __init__(self, first_name, last_name, age, phone_number):
        self.first_name = first_name
        self.last_name = last_name
        self.age = age
        self.phone_number = phone_number

    def describe_user(self):
        full_name = self.first_name + " " + self.last_name
        print(full_name + " is " + str(
            self.age) + " years old,and he's phone number is " + str(self.phone_number) + ".")

    def greet_user(self):
        full_name = self.first_name + " " + self.last_name
        print("Hello," + full_name + " !")


class Admin(User):
    def __init__(self, first_name, last_name, age, phone_number):
        super(Admin, self).__init__(first_name, last_name, age, phone_number)
        self.privileges = Priviliges()


class Priviliges():
    def __init__(self):
        self.privileges = ["can add post", "can delete post", "can ban user"]

    def show_privileges(self):
        print("The power of admin are:")
        for privilege in self.privileges:
            print(privilege)
#my_admin,py
from user import Admin,Priviliges
my_admin = Admin('张','三',27,15000000000)
my_admin.describe_user()
my_admin.privileges.show_privileges()
#9-12
# 多个模块 :将User 类存储在一个模块中,并将Privileges 和Admin 类存储在另一个模块中。再创建一个文件,在其中创建一个Admin 实例,并对其调用方
# 法show_privileges() ,以确认一切都依然能够正确地运行。
#user.py
class User(object):
    def __init__(self, first_name, last_name, age, phone_number):
        self.first_name = first_name
        self.last_name = last_name
        self.age = age
        self.phone_number = phone_number

    def describe_user(self):
        full_name = self.first_name + " " + self.last_name
        print(full_name + " is " + str(
            self.age) + " years old,and he's phone number is " + str(self.phone_number) + ".")

    def greet_user(self):
        full_name = self.first_name + " " + self.last_name
        print("Hello," + full_name + " !")
# priviliges.py
class Priviliges():
    def __init__(self):
        self.privileges = ["can add post", "can delete post", "can ban user"]

    def show_privileges(self):
        print("The power of admin are:")
        for privilege in self.privileges:
            print(privilege)
# admin.py
from priviliges import Priviliges
from user import User
class Admin(User):
    def __init__(self, first_name, last_name, age, phone_number):
        super(Admin, self).__init__(first_name, last_name, age, phone_number)
        self.privileges = Priviliges()
# my_admin.py
from admin import Admin
my_admin = Admin('张','三',30,19011111111)
my_admin.privileges.show_privileges()
my_admin.describe_user()
# 9-13
# 使用OrderedDict :在练习6-4中,你使用了一个标准字典来表示词汇表。请使用OrderedDict 类来重写这个程序,并确认输出的顺序与你在字典中添加键
# —值对的顺序一致。
from collections import OrderedDict
standard_dicts = OrderedDict()
standard_dicts['shorted']  = '排序'
standard_dicts['break'] = '排序'
standard_dicts['del'] = '排序'
standard_dicts['if'] = '排序'
standard_dicts['for'] = '排序'
for name,translation in standard_dicts.items():
    print(name + '的汉译:' + translation)

猜你喜欢

转载自blog.csdn.net/github_35707894/article/details/80833255