zoukankan      html  css  js  c++  java
  • #5 Python面向对象(四)

    前言

    本节将是Python面向对象的最后一篇博文了,这节将记录类的特殊方法、特殊成员方法、旧类和新类的不同,以及一些其他知识。Go!

    一、类的特殊方法

    Python有三种特殊方法:实例方法、静态方法、类方法。如果你读过一些源代码,你一定疑惑过这些代码:@staticmethod、@classmethod,前面见到的所有方法都是实例方法,实例方法的第一个参数为实例本身(self),由于实例方法经过前面几节已经掌握,所有本节将会熟悉剩下的两种特殊方法

    1.1 静态方法

    之前在类中编写的各种方法其实都是属于实例方法,每一个方法的第一个参数是实例本身(self),实例方法固然好用,但是在开发中,需要一些这样的方法:与类有关,在使用时不需要引用类和实例,也就是不能访问类变量和实例变量。这些方法通常用来作全局的配置方法,使代码更加简洁和安全。

    1.1.1 创建静态方法

    在类中的方法的前面使用装饰器: @staticmethod 即可,静态方法已经和普通函数没有太大区别,唯一的区别就是静态方法要通过对象来访问,看例:

     1 class Teacher:
     2     def __init__(self, name, gender):
     3         self.name = name
     4         self.gender = gender
     5 
     6     def talk(self):
     7         print('I am {}'.format(self.name))
     8 
     9     @staticmethod    # 创建 is_man 静态方法
    10     def is_man(gender):
    11         if gender == 'male':
    12             return 1
    13         return 0

    通过上例可以看到静态方法的创建比较简单,基本上已经和类无关了,按照普通的函数创建即可

    1.1.2 调用静态方法

    静态方法与函数的区别就是调用方式不同,函数直接调用即可,但是静态方法多多少少和类还是有一些关系的,那就是调用时需要对象来调用:

    zhangsan = Teacher('zhangsan', 'male')
    
    print(zhangsan.is_man('male'))
    
    
    # 运行结果:
    1

    注意:静态方法无法调用类变量和实例变量,这里就不作演示了。

    『防抄袭:读者请忽略这段文字,文章作者是博客园的MinuteSheep

    但是静态方法通常并不会在类外调用静态方法,而是直接在类内作为全局配置方法使用,例如:

     1 class Teacher:
     2     def __init__(self, name, gender):
     3         self.name = name
     4         self.gender = gender
     5 
     6     def talk(self):
     7         print('I am {}'.format(self.name))
     8 
     9     @staticmethod
    10     def is_man(gender):
    11         if gender == 'male':
    12             return 1
    13         return 0
    14 
    15     def eat(self):
    16         flag = self.is_man(self.gender)   # 作为全局配置使用
    17         if flag:
    18             print('I am man, I will eat 2 buns')
    19         else:
    20             print('I am woman, I will eat 1 bun')
    21 
    22 
    23 zhangsan = Teacher('zhangsan', 'male')
    24 
    25 zhangsan.eat()
    # 运行结果:
    I am man, I will eat 2 buns

    1.1.3 继承静态方法

    如果超类中有静态方法时,子类继承时会发生什么呢?

    class Teacher(object):
        def __init__(self, name, gender):
            self.name = name
            self.gender = gender
    
        @staticmethod
        def is_man(gender):
            if gender == 'male':
                return 1
            return 0
    
        def eat(self):
            flag = self.is_man(self.gender)   # 作为全局配置使用
            if flag:
                print('I am {}, I will eat 2 buns'.format(flag))
            else:
                print('I am {}, I will eat 1 bun'.formar(flag))
    
    
    class Chinese(Teacher):
        '''
        创建一个语文老师类,
        继承Teacher
        '''
    
        def __init__(self, name, gender):
            super().__init__(name, gender)
    
        @staticmethod   # 改写超类的静态方法
        def is_man(gender):
            if gender == 'male':
                return 'man'
            return 'woman'
    
    
    zhangsan = Chinese('zhangsan', 'male')
    
    zhangsan.eat()

    继承后将超类静态方法改写,运行结果j将按照子类的静态方法运行,结果如下:

    # 运行结果:
    I am man, I will eat 2 buns
    
    # 而不是按照超类的静态方法
    # I am 1,I will eat 2 buns

    1.2 类方法

     类方法,顾名思义是一种直接作用于类的方法。类方法和实例方法的区别就在于:类方法只能访问类变量,不能访问实例变量。

    1.2.1 创建类方法

    在类中的方法前面使用装饰器: @classmethod 即可,类方法和实例方法格式相似,类方法第一个参数必须是类本身(cls),看例:

    class Teacher(object):
        food = 'bun'
    
        def __init__(self, name, gender):
            self.name = name
            self.gender = gender
    
        @classmethod   # 创建类方法 eat
        def eat(cls):
            print(cls.food)

    通过上面代码可以看到,类方法的第一个参数为类本身,习惯上用cls表示,当然也可以用其他单词表示(这一点与self类似)

    1.2.2 调用类方法

    类方法的调用与实例方法无异,看例:

    zhangsan = Teacher('zhangsan', 'male')
    zhangsan.eat()
    
    
    # 运行结果:
    bun

    注意:类方法只能调用类变量,不能调用实例变量,这里就不作演示了

    『防抄袭:读者请忽略这段文字,文章作者是博客园的MinuteSheep

    类方法经常出现在源代码中,通常用来为类传入新的参数。

    二、类的特殊成员方法

    什么事特殊成员方法呢?其实你已经见过了,那就是类似__init__这样 __方法__ 形式的方法

    2.1 常用的特殊成员方法

    __init__   「构造函数,当实例化类对象时,会自动调用该方法」

    class Test:
        def __init__(self):
            print('实例化类对象后就会运行我')
    
    Test()
    
    # 运行结果:
    实例化类对象后就会运行我

    __del__   「析构函数,当类对象在内存中被释放时(也就是类对象运行完后),会自动调用该方法」

    class Test:
        def __del__(self):
            print('类对象释放后就会运行我')
    
    Test()
    
    
    # 运行结果:
    类对象释放后就会运行我

    __call__   「call方法,在类或者对象后加括号执行该方法」

    class Test:
        def __call__(self):
            print('我是博客园MinuteSheep,神马文库抄袭我的博文,不要脸')
    
    
    Test()()
    # 或者
    # obj = Test()
    # obj()
    
    # 运行结果:
    我是博客园MinuteSheep,神马文库抄袭我的博文,不要脸

    __dict__   「dict方法,查看类或者对象的所有成员信息」

    class Test:
    x = 1000 y = 'MS' print(Test.__dict__) # 运行结果: {'__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Test' objects>, 'x': 1000, '__doc__': None, 'y': 'MS', '__dict__': <attribute '__dict__' of 'Test' objects>}

    __doc__   「doc方法,查看类的描述信息」

    class Test:
        '''
        这里是类的描述信息
        '''
        x = 1000
        y = 'MS'
    
    
    print(Test.__doc__)
    
    
    # 运行结果:
    
        这里是类的描述信息

    三、旧类与新类

    Python3中,只有新类,旧类以及被移除, class 类名: 和 class 类名(object): 都是新类;Python2中, class 类名: 是旧类, class 类名(object): 是新类

    对旧类和新类了解一下即可

    3.1 旧类与新类的区别

    旧类:深度优先

    新类:广度优先

     1 # 在Python2中
     2 
     3 
     4 class A:
     5     pass
     6 
     7 
     8 class B(A):
     9     pass
    10 
    11 
    12 class C(B):
    13     pass
    14 
    15 
    16 class D(A, B, C):
    17     pass
    18 
    19 
    20 D()

    在Python2中,上述代码的调用顺序为:D->A->B->A->C->B->A

    明显是深度优先

     1 # 在Python2中
     2 
     3 
     4 class A(object):
     5     pass
     6 
     7 
     8 class B(A):
     9     pass
    10 
    11 
    12 class C(B):
    13     pass
    14 
    15 
    16 class D(A, B, C):
    17     pass
    18 
    19 
    20 D()

    在Python2中,上诉代码的调用顺序为:D->A->B->C->A->B->A->object

    明显是广度优先

    四、其他知识

    4.1 私有成员和私有方法

    接触类这么久了,你一定发现了又的方法和成员没有下划线,有的方法和成员只有一条下划线,有的方法和成员首尾各有两条下划线,这到底是什么含义呢?

    • 无下划线 foo:表示普通方法和成员

    • 一条下划线 _foo:表示被保护方法和成员,不能被 from xxx import _foo 导入

    • 两条下划线 __foo:表示私有方法和成员,只运行类本身进行访问

    • 首尾各两条下划线 __foo__:表示特殊方法,一般由系统自定义

    结语

    Python面向对象的知识到此结束,多加理解和联系才能真正掌握面向对象的知识,拜拜~

  • 相关阅读:
    ckplayer 一个不错的网页视频播放器
    onbeforeunload与a标签在IE中的冲突
    使用ckeditor 4.x 时遇到的问题及解决办法
    虚方法和重写方法的继承特性
    接口成员的访问
    基本框架(html)
    学习this关键字
    静态类
    方法参数
    Kubernetes之网络探究
  • 原文地址:https://www.cnblogs.com/minutesheep/p/10494463.html
Copyright © 2011-2022 走看看