Python 第五周 类

面向对象编程 是最有效的软件编写方法之一。
在面向对象编程中,你编写表示世界中的事物和情景的类,并基于这些类来创建对象。
编写类时,你定义一大类对象都有的通用行为。
基于类创建对象时,每个对象都自动具备这种通用行为,然后可根据需要赋予每个对象独特的个性。

目录

1. 创建和使用类

根据类创建实例

访问属性

 调用方法

创建多个实例

3.继承.

将实例用作属性

导入


1. 创建和使用类


使用类几乎可以模拟任何东西。下面来编写一个表示小狗的 简单类 Dog
它表示的不是特定的小狗,而是任何小狗。
对于大多数宠物狗,我们知道小狗会打滚,蹲下,它们还有年龄和名字。
我们用类包含他们。

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

class Dog():    #class 创建类  首字母大写的名称指的是类
    """一个模拟小狗的简单尝试"""
    def __init__(self,name,age):  #将方法 __init__()定义成了三个形参:self  name 和 age
                                # 在这个方法中,形参self 必不可少,还必须位于其他形参的前面。
        """初始化 name 和 age """
        self.name = name
        """ 以self为前缀的变量都可供类中的所有方法使用,我们还可以通过类的任何实例来访问这些变量。
            self.name = name 获取存储在形参 name 中的值,并将其存储到变量name中
             然后该变量被关联到当前创建的实例。
             像这样可通过实例访问的变量称为   {属性}  """
        self.age = age
    def sit(self):
        """模拟小狗被命令时蹲下"""
        print(self.name.title() + " is now sitting")
    def roll_over(self):
        """模拟小狗被命令时打滚"""
        print(self.name.title() + " is rolled over ! " )

方法 __init__()
类中的函数称为方法 ,__init__()是一个特殊的方法,每当你根据Dog类创建新实例时,Python都会自动运行它。
在这个方法的名称中,开头和末尾各有两个下划线,这是一种约定,为了避免Python默认方法与普通方法发生名称冲突
Python 调用这个 __init__()方法来创建Dog实例时,将自动传入实参self。每个与类相关联的方法调用都自动传递实参self
它是一个指向实例本身的引用 ,让实例能够访问类中的属性和方法。
我们创建Dog实例时,Python将调用Dog类的方法__init__()。我们将通过实参想Dog()传递名字和年龄。
self会自动传递,因此我们不需要传递它,
每当我们根据Dog类穿件实例时,都只需给最后两个形参(name 和 age )提供值。

根据类创建实例


"""创建一条名为 ”willie “ ,年龄为6的小狗。
遇到这行代码时,Python使用实参”willie“和6 调用Dog类中的方法__init__()。
方法__init__()创建一个表示特定小狗的示例,并使用我们提供的值来设置属性name和age。
方法__init__()并未包含return语句,但Python自动返回一个表示这条小狗的实例。
我们将这个实例存储在变量my_dog 中。
通常认为首字母大写的名称(Dog)指的是类,小写的名称(my_dog)指的是根据类创建的实例"""

 my_dog = Dog("willie",6)
 print("My dog 's name is " + my_dog.name.title() + "!") #  title() 首字母大写
 print("My dog is " + str(my_dog.age) + "years old !") #str(my_dog.age)将age的值6转换为字符串

访问属性

# 要访问实例的属性,可使用句点表示法  (my_dog.name)

 调用方法


根据Dog 类创建实例后,就可以使用句点表示法来调用Dog类中定义的任何方法。
表示小狗蹲下和打滚:

my_dog.sit()
my_dog.roll_over()

要调用方法,可指定实例的名称(这里是my_dog )和要调用的方法,并用句点分隔它们。
遇到代码my_dog.sit() 时,Python在类Dog 中查找方法sit() 并运行其代码。 Python以同样的方式解读代码my_dog.roll_over()

创建多个实例

 your_dog = Dog("lucy",5)
 your_dog.roll_over()
 your_dog.sit()

练习:

 餐馆 :
 创建一个名为Restaurant 的类,其方法__init__() 设置两个属性:restaurant_name 和cuisine_type 。
 创建一个名 为describe_restaurant() 的方法和一个名为open_restaurant() 的方法,其中前者打印前述两项信息,
 而后者打印一条消息,指出餐馆正在营业。 根据这个类创建一个名为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("Restauant name is " + self.restaurant_name.title() + " , cuisine_type is  " + self.cuisine__type)
    def open_resraurant(self):
        print("The restaurant is open")
my_restaurant = Restaurant("yellow braised chicken","Hunan cuisine")
my_restaurant.describe_restaurant()
my_restaurant.open_resraurant()

用户:创建一个名为User的类,其中包含属性 first_name 和 last_name ,还有用户简介通常会存储的其他几个属性。
在类中定义一个名为describe_user()的方法,它打印用户信息摘要;
再定义一个名为greet_user()的方法,它向用户发出个性化的问候

class User():
    def __init__(self,first_name,last_name,age,sex):
        self.first_name = first_name
        self.last_name = last_name
        self.age = age
        self.sex = sex
        self.full_name = str(self.first_name) + str(self.last_name)
        # self.full_name = self.full_name + self.last_name  这样写是错的
    def describe_user(self):
        print("My name is " +  self.full_name +", age is  " + self.age + ", sex is " + self.sex)
    def greet_user(self):
        print( "Hello ! " + self.full_name)
my = User("liu","wei","17","man")
my.describe_user()
my.greet_user()

2.使用类和实例

使用类来模拟现实世界中的很多情景,类编写好,大部分时间都将花在使用根据类创建的实例上.
你需要执行的一个重要任务是修改实例的属性
可以直接修改实例的属性,也可以编写方法以特定的方式进行修改
编写一个表示汽车的类:

class Car():
    def __init__(self,make,model,year):
        """  给属性指定默认值 , 类中的每个属性必须有初始值,哪怕这个值是0或空字符串
             如设置默认值时,在方法__init__()内指定这种初始值是可行的;
             如果你对某个属性这样做了,就无需包含为他提供初始值的形参."""
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0 # 现在添加一个名为 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):    # 再添加一个名为 read_odometer() 的方法,用于读取汽车的里程表
        """打印一条指出汽车历程的消息"""
        print("This car has " + str(self.odometer_reading) + " miles on it")

    def updata_odometer(self, mileage):
        """2,通过方法修改属性的值
             可对方法updata_odometer()进行扩展,使其在修改里程表读数时做些额外的工作.
             添加一些逻辑,进制任何人将里程表读数往回调:"""
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("禁止修改")

通过方法对属性的值进行递增
有时候需要将属性值递增特定的值,而不是设置为全新的值.假设买了一辆二手车,在购买到登记期间增加了100英里的里程.

    def increment_odometer(self,miles):
        """将里程数读数增加指定的量"""
        self.odometer_reading += miles
        self.odometer_reading = self.odometer_reading + miles

my_new_car = Car("bwm","x6",2004)
print("我的车的配置是:" + my_new_car.get_descriptive_name())
    # """ 这样的话,调用read_odometer这个方法一直是 0 , 我们需要修改这个属性的值
    # 有三种不同的方式:  1 ,直接通过实例进行修改;
    #                 2,通过方法进行设置;
    #                 3,通过方法进行递增(增加特定的值)"""
my_new_car.read_odometer()

my_new_car.updata_odometer(23)
my_new_car.read_odometer()

# 1,直接通过实例进行修改
my_new_car.odometer_reading = 23
my_new_car.read_odometer()

my_new_car.increment_odometer(100)
my_new_car.read_odometer()

练习:
就餐人数: 在刚才练习的餐馆 程序中,添加一个名为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  #创建属性 设置默认值为 0

    def describe_restaurant(self):
        print("Restauant name is " + self.restaurant_name.title() + " , cuisine_type is  " + self.cuisine__type)

    def open_resraurant(self):
        print("The restaurant is open")

    def set_number_served(self):
        """它让你能够设置就餐人数。调用这个方法并向它传递一个值,然后再次打印这个值"""
        print("就餐人数有:" + str(self.number_served) + "人")

    def increment_number_served(self,quantity):
        self.number_served += quantity

# my_restaurant = Restaurant("yellow braised chicken","Hunan cuisine")
# my_restaurant.describe_restaurant()
# my_restaurant.open_resraurant()
restaurant = Restaurant("yellow braised chicken","Hunan cuisine")
restaurant.increment_number_served(100)
restaurant.set_number_served()

尝试登录次数:
在刚在完成的 用户 程序 的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():
    def __init__(self,first_name,last_name,age,sex):
        self.first_name = first_name
        self.last_name = last_name
        self.age = age
        self.sex = sex
        self.full_name = str(self.first_name) + str(self.last_name)
        self.login_attempts = 0
        # self.full_name = self.full_name + self.last_name  这样写是错的

    def describe_user(self):
        print("My name is " +  self.full_name +", age is  " + self.age + ", sex is " + self.sex)

    def greet_user(self):
        print( "Hello ! " + self.full_name)

    def increment_login_attemps(self):
        """将login_attemps的值+1"""
        self.login_attempts += 1

    def reset_login_attempts(self):
        """将login_attemps的值重置为 0 """
        self.login_attempts = 0

    def prin_login_attempts(self):
        """打印出login_appempts的 值 """
        print(str(self.login_attempts))
#注意,属性名不能和函数名一样.
your = User("li","wei","12","man")
your.increment_login_attemps()  #调用值+1  函数
your.increment_login_attemps()  #调用值+1  函数
your.prin_login_attempts()      #调用打印  函数
your.reset_login_attempts()     #调用重置  函数
your.prin_login_attempts()      #调用打印  函数

# my = User("liu","wei","17","man")
# my.describe_user()
# my.greet_user()

3.继承.

编写类时,并非总要从空白开始 , 如果你要编写的类时另一个现成类的特殊版本
可使用继承。一个类继承另一个类时,它将自动获得另一个的所有属性和方法,原有的类 称为父类,而新类称为子类
子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法.

子类的方法init()
创建子类的实例时,Python首先需要完成的任务是给父类的所有属性赋值.为此,子类的方法__init()需要父类施以援手.
例如,现在模拟电动汽车.电动汽车是一种特殊的汽车,因此可以在前面创建的Car类的基础上创建新类ElectricCar.
这样就可以只需为电动汽车特有的属性和行为编写代码
创建一个简单的 ElectricCar类版本 , 它具备Car类的所有功能:

class ElectricCar(Car):     #定义子类时,必须在括号内指定父类的名称
    """电动汽车的独特之处"""
    def __init__(self,make,model,year): #接受创建Car 实例所需的 信息.
        """初始化父类的属性"""
        super().__init__(make,model,year) # super()是一个特殊函数,帮助Python将父类的子类关联起来
                                          # 这行代码让Python调用ElectricCar 的父类的方法__init__()
                                          # 让ElectricCar 实例包含父类的所有属性.
                                          # 父类也成为 超类
        self.battrey_size = 70  #定义 一个 属性, 电瓶.

    def describe_battery(self):         #创建一个方法 , 打印电瓶容量
        print("This car has a " +str(self.battrey_size) + " -kwh battery ")

    def fill_gas_tank():    # 假设Car类中 有一个名为fill_gas_tank()的方法.它对电动汽车没有意义.
                            # 重写的话  方法里面就不需要(self)了
        """电动车没有油箱"""
        print("This car doesn't need a gas tank!")

my_tesla = ElectricCar("tesla","model",2016)
print(my_tesla.get_descriptive_name())  #调用父类的的方法
my_tesla.describe_battery()         #调用子类的方法
my_tesla.fill_gas_tank()

子类定义属性和方法
让一个类继承另一个类后,可添加区分子类和父类 所需的 新属性和方法
添加一个电动汽车特有的属性(电瓶),以及一个描述该属性的方法.
我们将存储电瓶容量,并编写一个打印电瓶描述的方法.

重写父类的方法
对于父类的方法,只要它不符合子类模拟的实物的行为,都可对其进行重写.
为此,可在子类中定义一个这样的方法,即它与要重写的父类 方法 同名.
这样,Python将不会考虑这个父类方法,而只关注你在子类中定义的相应方法.
假设Car类中 有一个名为fill_gas_tank()的方法.它对电动汽车没有意义.
因此重写它.

将实例用作属性


使用代码模拟实物时,会发现给类添加的细节越来越多:属性和方法清单以及文件都越来越长.
在这种情况下,可能需要将类的一部分作为一个独立的类提取出来,
可以将大型类拆分成多个协同工作的小类.
例如,不断给ElectricCar 类添加细节时,可能会发现其中包含很多专门针对汽车电瓶的属性和方法
在这种情况下 可将这些属性和方法提取出来,放到另一个名为 Battery的类中,并将一个Battery实例用作ElecTricCar类的一个属性

class Battery():
    """模拟电动汽车电瓶的简单尝试"""
    def __init__(self,battery_size = 70):
        self.battery_size = battery_size

    def describe_battery(self):
        print("This car has a " + self.battery_size + " -Kwh battery")

    # def get_range(self):
    #     if self_battery == 70:
    #         range = 240
    #     elif self.battery_size == 85:
    #         range = 270
class ElectricCar(Car):
    def __init__(self,make,model,year):
        super().__init__(make,model,year)
        self.battery = Battery()    #将实例作为了属性

 练习:
 编写一个名为IceCreamStand的类,让他继承 之前完成的 Restaurant类.
 添加一个名为flavors的属性,用于存储一个由各种口味的冰激凌组成的列表
 编写一个显示这些冰激凌的方法,
 创建一个IceCreamStand的实例,并调用这个方法

class IceCreamStand(Restaurant):
    def __init__(self,restaurant_name,cuisine_type):
        super().__init__(restaurant_name,cuisine_type)
        self.flavors = ["香草味","草莓味","抹茶味"]
    def show(self):
        for i in self.flavors:
            print(i)
icecream = IceCreamStand("可爱多","冰激凌店")
icecream.show()

管理员:编写一个名为Admin的类,让它继承 之前编写的 User类.
添加一个名为privilages的属性,用于存储一个由字符串 组成的列表.
编写一个名为show_privilages()的方法,它显示管理员的权限.
创建一个 Admin 实例,并调用这个方法.

class User():
    def __init__(self,first_name,last_name,age,sex):
        self.first_name = first_name
        self.last_name = last_name
        self.age = age
        self.sex = sex
        self.full_name = str(self.first_name) + str(self.last_name)
        self.login_attempts = 0
        # self.full_name = self.full_name + self.last_name  这样写是错的

    def describe_user(self):
        print("My name is " +  self.full_name +", age is  " + self.age + ", sex is " + self.sex)

    def greet_user(self):
        print( "Hello ! " + self.full_name)

    def increment_login_attemps(self):
        """将login_attemps的值+1"""
        self.login_attempts += 1

    def reset_login_attempts(self):
        """将login_attemps的值重置为 0 """
        self.login_attempts = 0

    def prin_login_attempts(self):
        """打印出login_appempts的 值 """
        print(str(self.login_attempts))

class Admin(User):
    def __init__(self,first_name,last_name,age,sex,role):
        super().__init__(first_name,last_name,age,sex)
        self.privilages = ["can add post" ,"can delete post" ,"can ban user"]
        self.role = role
        self.privil = Privileges()
    def show_privilages(self):
        if self.role == "admin": #一定不要忘记 引号
            print("他的权限是" + self.privilages[0])
        elif self.role == "user":
            print("他的权限是" + self.privilages[1])
        else:
            print("他的权限是" + self.privilages[2])
john = Admin("jo","hn","12","man","1")
john.show_privilages()

权限:编写一个名为Privileges 的类,它只有一个属性——privileges ,其中存储了练习刚才所说的字符串列表。
将方法show_privileges() 移到这个类中。
在Admin 类中,将一个Privileges 实例用作其属性。创建一个Admin 实例,并使用方法show_privileges() 来显示其权限。

写不出来了

导入

from car import Car     #让python打开模块car ,并导入其中的Car类
from car import Car, ElectricCar 从一个模块中导入多个类.

Python标准库
Python标准库是一组模块,安装的Python都包含它。可使用标准库中的任何函数和类,为此只需在程序开头包含一条简单的import语句
from collections import OrderedDict
字典让你能够将信息关联起来,但它们不记录你添加键—值对的顺序。要创建字典并记录其中的键—值对的添加顺序,可使用模块collections 中的OrderedDict类。
OrderedDict 实例的行为几乎与字典相同,区别只在于记录了键—值对的添加顺序。

favorite_languages = OrderedDict() #导入Python库中的类
favorite_languages["jen"] = "python"
favorite_languages["sarah"] = "c"
for name,language in favorite_languages.items():
    print(name.title() + " 's favorite languaes is " + language.title() + ".")

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值