Advertisement

Python蟒蛇书学习笔记——第九章 类

阅读量:

Python蟒蛇书学习笔记——第九章 类

复制代码
    #初稿完成时间:2022/7/3
    #作者:XP钉子户

面向对象编程 是Python语言特色之一。编写 时,可以提前设计好各种通用行为。基于类所创建的对象 均拥有此类通用行为,根据类来创建对象称为实例化

​ 下面为本笔记的目录,可以点击目录跳转到对应的部分阅读。

文章目录

  • Python蟒蛇书学习笔记——第九章 类
    • 9.1 创建和使用类

    • 9.2 根据类创建实例

      • 9.2.1 类创建实例的方法
      • 9.2.2 访问实例的属性和调用实例的方法
      • 9.2.3 给属性指定默认值
      • 9.2.4 修改属性的值
    • 9.3 继承

      • 9.3.1 子类的继承与定义属性和方法
      • 9.3.2 重写父类的方法
      • 9.3.3 将实例用作属性
    • 9.4 导入类

      • 9.4.1 导入单个类
      • 9.4.2 在一个模块中存储多个类
      • 9.4.3 从一个模块中导入多个类
      • 9.4.4 导入整个模块
      • 9.4.5 导入模块中的所有类
      • 9.4.6 使用别名
    • 9.5 Python标准库

    • 9.5 Python标准库

9.1 创建和使用类

​ 创建类的方法:

复制代码
    class Dog:
    def __init__(self,name,age):  
        """初始化函数,每次根据Dog类创建新实例时,Python都会自动运行它。"""
        self.name=name
        self.age=age
    def sit(self):
        print(f"{self.name} is now sitting.")
    def roll_over(self):
        print(f"{self.name} rolled over!")

​ 注意:此处出现了self 。self类似于Java语言内的this ,只出现在类里面(换言之,实例化之后就不会出现self)。以self为前缀的变量可供类中的所有方法使用,可以通过任何类的实例来访问。如:

复制代码
    my_dog = Dog('Willie',6)  #实例化一个对象my_dog
    print(my_dog.name)
    print(my_dog.age)

​ 此时程序的输出为:

复制代码
    willie
    6

​ 像这种可以通过实例访问的变量称为属性

9.2 根据类创建实例

9.2.1 类创建实例的方法

​ 根据类创建实例的方法:

复制代码
    class Dog:
    ...
    my_dog = Dog('willie',6)  #这里的'willie'为name变量的初始值,6为age变量的初始值

​ 此处通过Dog类创建了一个my_dog实例。这个创建过程中赋予了两个实参,在实例化时,Python会自动执行Dog类里面的初始化函数,并根据这个函数对my_dog的参数进行初始化。

​ Python也支持对同一个类创建多个实例。每个实例都拥有着类别相同的属性。

9.2.2 访问实例的属性和调用实例的方法

​ 下面,我们对于my_dog实例访问属性和调用方法。

复制代码
    print("My dog's name is {}".format(my_dog.name))
    print("My dog's age is {}".format(my_dog.age))
    my_dog.sit()
    my_dog.roll_over()

​ 程序的运行结果如下:

复制代码
    My dog's name is willie
    My dog's age is 6
    willie is now sitting.
    willie rolled over!

9.2.3 给属性指定默认值

​ 可以通过在类的初始化函数中直接赋予self的某个属性默认值。如:

复制代码
    class Dog:
    def __init__(self,name,age):  #此处可以设定形参sex,也可以不设定。
        self.name=name
        self.age=age
        self.sex='male'
    def get_sex(self):
        print("Your dog's sex is {}.".format(self.sex))
    my_dog=Dog('willie',6)
    my_dog.get_sex()

​ 程序的运行结果如下:

复制代码
    Your dog's sex is male.

9.2.4 修改属性的值

​ 修改属性的值有两种方法。

​ 首先可以通过实例直接访问。如:

复制代码
    class Dog:
    ...
    my_dog=Dog('willie',6)
    my_dog.sex='female'    #直接通过实例访问
    my_dog.get_sex()

​ 程序的运行结果如下:

复制代码
    Your dog's sex is female.

​ 其次,可以在类里面定义一个修改属性的方法,使用实例时调用其方法来修改属性的值。如:

复制代码
    class Dog:
    def __init__(self,name,age):  #此处可以设定形参sex,也可以不设定。
        self.name=name
        self.age=age
        self.sex='male'
    def change_sex(self,sex):     #修改狗狗的性别,若不符合标准则报错
        if(sex=='male' or sex=='female'):
            self.sex=sex
        else:
            print("Sorry, the third sex is not supported now.")
    def get_sex(self):
        print("Your dog's sex is {}.".format(self.sex))
    my_dog=Dog('willie',6)
    print("Before changes:")
    my_dog.get_sex()
    s = input("Input {}'s sex:".format(my_dog.name))
    my_dog.change_sex(s)
    print("After changes:")
    my_dog.get_sex()

​ 程序输出如下:

复制代码
    Before changes:
    Your dog's sex is male.
    Input willie's sex:female
    After changes:
    Your dog's sex is female.

9.3 继承

​ 编写类时,不一定都要从头开始编写。如果要编写的类是一个现有的类的特殊版本,那么可以使用继承 。一个类继承另一个类时,将自动获得原有的类的所有属性和方法。

​ 原有的类叫做父类 ,新建的类叫做子类 。子类不仅继承了父类的所有方法,同时还可以定义属于自己的属性和方法。显然,子类拥有父类所有的属性和方法,而父类不一定拥有子类所有的属性和方法。

9.3.1 子类的继承与定义属性和方法

​ 继承新类时,通常要调用父类的方法__init__()。这将初始化在父类__init__()中定义的所有属性,从而让子类也包含这些属性。

​ 例如,我们根据已有的Dog类,新建一个Chinese_Dog类,并让Chinese_Dog类继承Dog类。

复制代码
    class Dog:
    def __init__(self,name,age): 
        self.name=name
        self.age=age
        self.sex='male'
    class Chinese_Dog(Dog):                          #让Chinese_Dog类继承Dog类
    def __init__(self,name,age,Chinese_name):    #定义子类的初始化函数
        super().__init__(name,age)               #调用父类的初始化函数,参数不用再加self哦
        self.Chinese_name=Chinese_name           #在父类初始化函数的基础上,初始化子类特有的参数
    def Get_Basic_Info(self):                    #定义子类特有的方法
        print(my_Chinese_dog.name)
        print(my_Chinese_dog.age)
        print(my_Chinese_dog.Chinese_name)
    my_Chinese_dog=Chinese_Dog('johnson',5,'wangcai')
    my_Chinese_dog.Get_Basic_Info()

​ 程序输出如下:

复制代码
    johnson
    5
    wangcai

super()是一个特殊的函数,其能调用父类的方法。叫super的原因是:父类的别名是 超类(superclass)。

9.3.2 重写父类的方法

​ 对于父类的方法,如果某些方法对于子类不再适用,就可以进行重写 。为此,可在子类中定义一个与要重写的父类方法同名的方法。这样,Python就不会考虑同名的父类方法,而只关注你在子类中所定义的这个同名方法。

​ 例如,对于以下类,如果我们不对父类的Show_Nation()函数重写:

复制代码
    class Dog:
    def __init__(self,name,age): 
        self.name=name
        self.age=age
    def Show_Nation(self):
        print("{} is from the United States.".format(self.name))
    class Chinese_Dog(Dog):                          
    def __init__(self,name,age,Chinese_name):    
        super().__init__(name,age)               
        self.Chinese_name=Chinese_name           
    my_dog=Chinese_Dog('Johnson',5,'wangcai')
    my_dog.Show_Nation()

​ 此时程序的输出如下:

复制代码
    Johnson is from the United States.

​ 很显然,对于中国的狗狗来说,籍贯应该归为中国。因此,在子类中,要对父类的Show_Nation()函数重写:

复制代码
    class Dog:
    def __init__(self,name,age): 
        self.name=name
        self.age=age
    def Show_Nation(self):
        print("{} is from the United States.".format(self.name))
    class Chinese_Dog(Dog):                          
    def __init__(self,name,age,Chinese_name):    
        super().__init__(name,age)               
        self.Chinese_name=Chinese_name     
    def Show_Nation(self):    #重写父类的Show_Nation()函数
        print("{} is from the People's Republic of China.".format(self.name))
    my_dog=Chinese_Dog('Johnson',5,'wangcai')
    my_dog.Show_Nation()

​ 程序输出如下:

复制代码
    Johnson is from the People's Republic of China.

9.3.3 将实例用作属性

​ 对于一个类来说,如果类里面的属性和方法过于冗杂,可以考虑将类的一部分提取出来作为一个独立的类。可以将大型类拆分成多个协同合作的小类。

​ 例如,对于下面的Dog类:

复制代码
    class Dog:
    def __init__(self,name,age):
        self.name=name
        self.age=age
        self.nation='China'
        self.province='Hainan'
        self.city='Haikou'
    def Show_Address(self):
        print(f"{self.name} is from:")
        print(f"{self.city} City,{self.province} Province, {self.nation}")

​ 这个类里面包含了三个关于地址的参数还有一个方法,我们可以把它们单独提取出来,在Dog类之前新建一个address类:

复制代码
    class address:    #将原有Dog类里面关于地址的参数和方法提取到address类里面
    def __init__(self,nation="China",province='hainan',city='haikou'):
        self.nation=nation
        self.province=province
        self.city=city
    def Show_Address(self):
        return ("{} City, {} Province, {}".format(self.city,self.province,self.nation))
    class Dog:
    def __init__(self,name,age): 
        self.name=name
        self.age=age
        self.Address=address()  #创建一个名为Address的实例,并把Address实例当做Dog类的属性
    my_dog=Dog('willie',5)
    print(my_dog.name.title()+" is from:")
    print(my_dog.Address.Show_Address().title()) #在实例my_dog中查找属性address,并对存储在该属性中的address实例调用方法

​ 程序的输出为:

复制代码
    Willie is from:
    Haikou City, Hainan Province, China

​ 在这个例子里面,我们把有关地址的参数和方法单独放在了address类里面,然后又在Dog类里面创建一个名为Address的实例,并把Address实例当做Dog类的属性。

​ 需要注意的是:这样单独提取的类必须放在原有类的前面!

9.4 导入类

​ 前面我们学过,可以将程序中的一部分函数保存在另一个同文件目录下的py文件,然后通过import的方式导入源程序中。对于类,Python也支持这样的操作:可以将类存储在模块中,然后在主程序中导入所需的模块。

9.4.1 导入单个类

​ 我们来尝试一下在主程序中导入单个类。

设主程序名为main.py,其源代码为:

复制代码
    class Dog:
    def __init__(self,name,age): 
        self.name=name
        self.age=age
    def Show_Nation(self):
        print("{} is from the United States.".format(self.name.title()))
    my_dog=Dog('willie',6)
    my_dog.Show_Nation()

​ 我们现在将Dog类单独放在名为dog.py的文件中(该文件与main.py放置在同一目录下)。

​ 此时dog.py的源代码为:

复制代码
    class Dog:
    def __init__(self,name,age): 
        self.name=name
        self.age=age
    def Show_Nation(self):
        print("{} is from the United States.".format(self.name.title()))

​ main.py的源代码为:

复制代码
    from dog import Dog    #from后面为所打开的模块名称,import后面为所导入的类名
    my_dog=Dog('willie',6)
    my_dog.Show_Nation()

运行main.py,程序输出为:

复制代码
    Willie is from the United States.

9.4.2 在一个模块中存储多个类

​ Python支持在一个模块中存储任意数量的类,当然也包括若干子类和父类。

​ 例如,我们运用原来学过的继承的知识,在dog.py中同时存储父类和子类:

复制代码
    class Dog:
    def __init__(self,name,age): 
        self.name=name
        self.age=age
    def Show_Nation(self):
        print("{} is from the United States.".format(self.name))
    class Chinese_Dog(Dog):                          
    def __init__(self,name,age,Chinese_name):    
        super().__init__(name,age)               
        self.Chinese_name=Chinese_name     
    def Show_Nation(self):    #重写父类的Show_Nation()函数
        print("{} is from the People's Republic of China.".format(self.name))

​ 在main.py中,我们新建一个子类的实例,然后调用子类的方法:

复制代码
    from dog import Chinese_Dog     #主程序只实例化了Chinese_Dog类,因此导入子类即可
    my_dog=Chinese_Dog('Johnson',5,'wangcai')
    my_dog.Show_Nation()

​ 程序输出如下:

复制代码
    Johnson is from the People's Republic of China.

9.4.3 从一个模块中导入多个类

​ 从一个模块中导入两个类的方法如下:

复制代码
    from dog import Chinese_Dog,Dog

​ 由此可类推导入三个乃至多个类的方法。

9.4.4 导入整个模块

​ 从一个模块中导入所有类的方法如下:

复制代码
    import dog

​ 需要注意的是,导入整个模块后,要使用句点表示法来访问所需要的类。还是以9.4.2为例,若main.py的首行改为导入dog模块,则后面访问dog模块里面的Chinese_Dog类时应改成:

复制代码
    my_dog=dog.Chinese_Dog('Johnson',5,'wangcai')
    my_dog.Show_Nation()

9.4.5 导入模块中的所有类

​ 可以使用通配符*来导入所有的类:

复制代码
    from dog import *

然而并不推荐这么做 ,原因有二:首先,这种写法不能让程序员很直观地看出使用了dog模块的哪些类;其次,如果导入的不同模块之间有同名的类(例如模块1和模块2中都有dog类),则主程序会发生难以预测的错误。因此,建议根据9.4.4的做法,导入整个模块,然后使用句点表示法来访问 ,这样可以大大避免同名而造成的指代不清的问题。

9.4.6 使用别名

​ 可以在导入时通过as来制定别名。例如:

复制代码
    from dog import Chinese_Dog as CD
    my_dog=CD('willie',6,'wangcai')

9.5 Python标准库

​ Python标准库是安装Python时默认包含的一些模块,可以通过import来导入标准库模块,从而自由使用里面的类和函数。例如,调用Python标准库模块random:

复制代码
    from random import randint
    print(randint(1,100))    #随机生成一个位于(1,100)区间内的整数

​ 在模块random中,还有一个函数名为choice()。它以一个列表或元组为参数,随机返回其中一个元素:

复制代码
    from random import choice
    pets=['dog','cat','mouse','rabbit','pig','sheep']
    print('I will choose a pet irregularly.')
    print(f'I choose {choice(pets)}.')

9.5 Python标准库

​ Python标准库是安装Python时默认包含的一些模块,可以通过import来导入标准库模块,从而自由使用里面的类和函数。例如,调用Python标准库模块random:

复制代码
    from random import randint
    print(randint(1,100))    #随机生成一个位于(1,100)区间内的整数

​ 在模块random中,还有一个函数名为choice()。它以一个列表或元组为参数,随机返回其中一个元素:

复制代码
    from random import choice
    pets=['dog','cat','mouse','rabbit','pig','sheep']
    print('I will choose a pet irregularly.')
    print(f'I choose {choice(pets)}.')

全部评论 (0)

还没有任何评论哟~