Python从入门到精通(十四)Python面向对象的开发2,封装,多继承,多态都了解了么

Posted 码农飞哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python从入门到精通(十四)Python面向对象的开发2,封装,多继承,多态都了解了么相关的知识,希望对你有一定的参考价值。

您好,我是码农飞哥,感谢您阅读本文,欢迎一键三连哦
本文主要介绍Python的封装和多态这两个重要特性。
干货满满,建议收藏,需要用到时常看看。 小伙伴们如有问题及需要,欢迎踊跃留言哦~ ~ ~。

前言

上一篇文章我们介绍了Python面向对象的一些基本概念。这一篇文章继续总结Python面向对象的一些详细知识点。本文主要介绍面向对象的封装和多态两个重要的特性。

@property装饰器

当@property装饰器修饰方法的时,就可以直接通过方法名来调用方法,而不需要加上后面的()小括号。其语法格式是:

@property
def 方法名(self)
    代码块

其一般应用于要对类序列化的方法上,如下面Student类。

class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score

    @property
    def serialize(self):
        return {"name": self.name, "score": self.score}
student = Student('张三', 100)
print(student.serialize)

Python的封装机制

在Java的其他的面向对象的语言中,可以通过public,protected,private等访问限制修饰符来表示一个方法可被访问的范围。在Python中没有与之对应的访问修饰符。Python中的变量和方法默认都是公有(public)的,说白了,就是谁都可以访问。那么,在Python中有没有一种机制来让一个方法私有呢?答案是有的。
在Python中如果类中的变量或函数,其名称以双下划线"__"开头,则该变量(函数)为私有变量(私有函数)其属性等同于private。私有方法的意思是,只能在类的内部访问该方法,不能在类的外部访问。

class Student2(object):
    def __init__(self):
        pass

    def get_gender(self):
        return self.__gender

    def set_gender(self, gender):
        self.__gender = gender

    # 定义私有方法
    def __display(self):
        print(self.__gender)


student = Student2()
student.set_gender('男')
student.__display()

运行结果是:

Traceback (most recent call last):
  File "/python_demo_1/demo/oop/Student2.py", line 36, in <module>
    student.__display()
AttributeError: 'Student2' object has no attribute '__display'

如上代码所示,直接访问私有方法__display话会报错,提示找不到__display方法。
需要注意的是:如果是类方法或者类变量的话,哪怕方法名前缀是有__修饰还是可以访问,但是不建议这样做。因为通过__修饰的话就默认是私有方法。
不过在python中方法名的前缀和后缀都有__修饰的方法是Python的内置方法,在自定义的方法中不建议这样给方法命名。

super()函数

super函数用于子类继承父类,并且重写了父类的类实例方法或者构造方法时。如果此时要调用父类方法,可以通过super函数来调用。

class Animal:
    def __init__(self, food):
        self.food = food


class People(Animal):
    def __init__(self, name, food):
        super().__init__(food)
        self.name = name

    def say(self):
        print("我是人,名字是:{0},吃的食物是:{1}".format(self.name, self.food))


people = People('张三', '熟食')
people.say()

运行结果是:我是人,名字是:张三,吃的食物是:熟食
如上代码:People类继承了Animal类,而Animal类中有个实例属性food。在People类的构造方法中可以通过super().__init__(food)方法来调用其父类Animal类的构造方法实现对参数的注入。

多继承的情况

Python是支持多继承的,如果子类继承的多个父类中包含同名的类实例方法,则子类对象在调用该方法时,会优先选择排在最前面的父类的实例方法,显然,构造方法 也是如此。使用super()函数。但如果涉及多继承,该函数只能调用第一个直接父类的构造方法。

class People:
    def __init__(self, name):
        self.name = name

    def say(self):
        print("我是人,名字是:", self.name)


class Animal:
    def __init__(self, food):
        self.food = food

    def display(self):
        print("我是动物,我吃", self.food)


class Person(People, Animal):
    # 自定义构造方法
    def __init__(self, name, food):
        super().__init__(name)
        # super(Person,self).__init__(name)
        # 调用其他父类的构造方法,需手动给self传值
        Animal.__init__(self, food)


per = Person('张三', '熟食')
per.say()
per.display()

运行结果是:

我是人,名字是: 张三
我是动物,我吃 熟食

type()函数

type()函数属于Python内置函数,通常用来查看某个变量的具体类型。其高级的用法是创建一个自定义的类型(也就是创建一个类)。其语法结构是:

type(obj) 
type(name, bases, dict)

第一种语法格式是用来查看某个变量(类对象)的具体类型,obj表示某个变量或者类对象。
第二种语法用来创建类,其中name表示类的名称,bases表示一个元组,其中存储的是该类的父类;dict表示一个字典,用于表示类内部定义的属性或者方法。
第一种语法举个例子:

print(type(123) == type(456))
print(type(123) == int)
print(type('abc') == type(123))

运行结果是:

True
True
False

第二种语法举个例子:

def say(self):
    print('我要学Python!')
# 使用type()函数创建类
TypeTest = type("TypeTest", (object,), dict(say=say, name="码农飞哥"))
# 创建一个TypeTest实例对象
typeTest = TypeTest()
typeTest.say()
print(typeTest.name)

运行结果是:

我要学Python!
码农飞哥

如上通过type函数创造了一个名叫TypeTest的类,该类继承于Object类。该类中定义一个方法say,一个类变量name。

多态

多态是继封装,继承之后,面向对象的第三大特性。
在生活中,比如跑的动作,小猫,小狗和大象,跑起来是不一样的;在比如飞的动作,昆虫,鸟类和飞机,飞起来的动作也是不一样的。可见,同一行为,通过不同的事物,可以体现出不同的形态。而多态就是用来描述这样的状态的。
多态需要满足的两个条件是:

  1. 继承:多态一定是发生在子类和父类之间。
  2. 重写:子类必须重写父类的方法。
    如下代码:
class Animal(object):
    def run(self):
        print('动物奔跑')
class Dog(Animal):
    def run(self):
        print('小狗奔跑')
class Cat(Animal):
    def run(self):
        print('小猫奔跑')


animal=Animal()
animal.run()

animal = Dog()
animal.run()

animal = Cat()
animal.run()

运行结果是:

动物奔跑
小狗奔跑
小猫奔跑

Dog和Cat类都继承了Animal类。并且这两个类都重写了Animal类的run方法。通过给变量animal赋值不同的对象再使其调用run方法时产生不同的效果。当然,这还不是多态的精髓,多态的精髓就是可以传入不同的对象使其产生不同的效果。如下代码所示,还是上面的那个例子,在此处定义一个WhoRun类,该类定义了一个run方法,在run方法中增加了一个who参数。

class WhoRun:
    def run(self, who):
        who.run()
class Animal(object):
    def run(self):
        print('动物奔跑')

class Dog(Animal):
    def run(self):
        print('小狗奔跑')

class Cat(Animal):
    def run(self):
        print('小猫奔跑')

a = WhoRun()
a.run(Animal())
a.run(Dog())
a.run(Cat())

运行结果是:

动物奔跑
小狗奔跑
小猫奔跑

通过向run方法中传入不同的对象,然后通过传入的对象来调用run方法以得到不同的效果。这就是著名的“鸭子模型”。

枚举类

针对一些具有特殊含义的类,其实例化对象的个数往往是固定的,比如用一个类表示月份,则该类的实例对象最多有12个;再比如用一个类表示季节,则该类的实例对象最多4个。再比如用一个类表示性别,则该类的实例对象最多2个。

from enum import Enum


class Color(Enum):
    # 为序列值制定value值
    red = 1
    green = 2
    blue = 3
# 获取枚举类成员的3种方式
print(Color.red)
print(Color['red'])
print(Color(1))
# 调取枚举类成员的value和name
print(Color.red.value)
print(Color.red.name)

# 遍历枚举类中所有成员的2种方式
for color in Color:
    print(color)

运行结果是:

Color.red
Color.red
Color.red
1
red
Color.red
Color.green
Color.blue

总结

本文详细介绍了Python类一些比较重要的知识点:比如多态,封装等等,还介绍了枚举类都是在实际开发中会经常使用到的知识点。

Python知识图谱

为了更好帮助更多的小伙伴对Python从入门到精通,我从CSDN官方那边搞来了一套 《Python全栈知识图谱》,尺寸 870mm x 560mm,展开后有一张办公桌大小,也可以折叠成一本书的尺寸,有兴趣的小伙伴可以了解一下------扫描下图中的二维码即可购买。


我本人也已经用上了,感觉非常好用。图谱桌上放,知识心中留。

我是码农飞哥,再次感谢您读完本文

以上是关于Python从入门到精通(十四)Python面向对象的开发2,封装,多继承,多态都了解了么的主要内容,如果未能解决你的问题,请参考以下文章

Python从入门到精通(二十四)Python定时执行任务的姿势

MySQL从入门到精通高级篇(二十四)EXPLAIN中select_type,partition,type,key,key_len字段的剖析

MySQL从入门到精通高级篇(二十四)EXPLAIN中select_type,partition,type,key,key_len字段的剖析

MySQL从入门到精通高级篇(二十四)EXPLAIN中select_type,partition,type,key,key_len字段的剖析

Python从入门到精通(十三)Python面向对象的开发,没有对象怎么能行呢?

Python从入门到精通(十三)Python面向对象的开发,没有对象怎么能行呢?