Python:深入类和对象

鸭子类型和多态
多态的概念是来源与Java和C#这一类强行语言中,而Python就是崇尚的"鸭子类型"
动态语言调用实例化对象类型,只要方法存在,参数正确就可以实现的,这就是动态语言的"鸭子类型"
所谓多态:就是定义类型时和运行类型时不一样就是多态

a = [1, 2]   # list
b = [3, 4]   # list
d = (5, 6)   # tuple
e = {7, 8}   # set   # [1, 2, 8, 7]  集合是无序的

# 传参:self, iterable   什么是iterable  iterable相当于是可迭代的对象
# 可迭代的对象可以通过for循环来取出来
a.extend(e)   #可传e,b,d 这就是鸭子类型
print(a)

运行结果:

[1, 2, 8, 7]
class Person0(object):
    def say(self):
        print('Person0正在讲话')


class Person1(object):
    def say(self):
        print('Person1正在讲话')


class Person2(object):
    def say(self):
        print('Person2正在讲话')


Persons = [Person0, Person1, Person2]
for Person in Persons:
    Person().say()

运行结果:

Person0正在讲话
Person1正在讲话
Person2正在讲话

抽象基类(abc模块)
抽象基类就是类里定义了纯虚成员函数的类。纯虚函数只提供了接口,并没有具有实现。抽象基类不能被实例化(不能创建对象),通常是作为基类提供子类继承函数,实现具体的接口

抽象基类就是定义各种方法而不是做具体实现的类,任何继承自抽象基类的类必须实现这写方法,否则无法实例化

应用场景
- 判断某个对象的类型

class Person(object):
    def __init__(self, names):
        self.names = names

    def say(self):
        print('我正在讲话')

    def __len__(self):
        return len(self.names)


# 实例化对象
p = Person(['钢铁侠', '蜘蛛侠', '绿巨人'])
print(len(p))

# hasattr  判断某个对象中含有该方法
print(hasattr(p, '__len__'))   # 判读某个对象的实例
  • 我们需要强制某个子类必须完成的某些方法
class Person(object):
    def get(self,key):
        raise ValueError  # 主动抛出异常

    def set(self,key,value):
        raise ValueError

r = Person()
r.get('vale')

运行结果:

    raise ValueError # 主动抛出异常
ValueError

improt abc模块

import abc

class Person(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def get(self,key):
        raise ValueError  # 主动抛出异常
    @abc.abstractmethod
    def set(self,key,value):
        raise ValueError

r = Person()
# r.get('vale')

运行结果:

TypeError: Can't instantiate abstract class Person with abstract methods get

isinstance 和 type 的区别
isinstance:会考虑类的继承
type:不会考虑类的继承

class A(object):
    pass


class B(A):
    pass


class C(B):
    pass


b = C()
print(isinstance(b, A))  # 判断isinstance是否会考虑继承的关系
print(type(b) is B)      # is 判断的是内存地址值

# 运行结果
True
False

类变量和对象变量


class A():
    aa = 1

    def __init__(self, x, y):
        self.x = x
        self.y = y


a = A(1, 2)
# print(a.x, a.y, a.aa)    # 实例化类对象可以向上查找
# print(A.x)    # 调用类不能向下查找


A.aa = 22  # 相当于重新赋值
a.aa = 11  # 相当于添加了一个实例属性
print(A.aa)
print(a.aa)

# 运行结果
22
11

类属性和实例属性以及查找方法
MRO算法
MRO算法

Python2.2之前的算法:金典类

DFS(deep first search):A->B->D->C->E

Python2.2版本之后,引入了BFS(广度优先搜索)

BFS:A->B->C->D

在Python2.3之后,Python采用了C3算法

Python新式类继承的C3算法:C3算法的介绍

Python中的自省机制
什么是Python中的自省机制?

  • 自省是通过一定的机制查询的对象的内容结构
  • 自省相当于就是在生活中相当于是一种自我行为检测

Python中常见的自省机制函数
dir()、type()、isinstance()、hansater()

什么是dir():

  • 简单来讲dir()相当于就是把这个对象中有的属性方法全部以列表的方式来存放到dir()中里面
print(dir(list))
#运行结果:
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

什么是type():?

  • type()是用来判断当前的类型属于什么类型
a = 1
print(type(a))

运行结果:

<class 'int'>

什么是isinstance():?

  • 用来判断一个对象是否是已知的数据类型
  • 当结果是已知的数据类型时,返回的结果为True
  • 当结果不是已知的数据类型时,返回的结果为False
a = 1
print(isinstance(a,int))
# 运行结果
True

什么是hasattr():?

  • 判断某个对象中含有该方法
  • 当含有该方法时,返回True
  • 当没含有该方法时,返回False
class Person(object):
    def __init__(self, names):
        self.names = names

    def say(self):
        print('我正在讲话')

    def __len__(self):
        return len(self.names)


# 实例化对象
p = Person(['钢铁侠', '蜘蛛侠', '绿巨人'])
print(len(p))

# hasattr  判断某个对象中含有该方法
print(hasattr(p, '__len__'))   # 判读某个对象的实例

运行结果:

3
True

super()函数
在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法,这就是super存在的意义
重写了构造方法为什么还要使用super()?
减少代码的复用
扩展子类属性
有些属性父类中有的方法就不需要重写

# -*- coding: utf-8 -*- 
# @Time : 2019/12/26 15:32 
# @Author : 大数据小J 
# @File : demo12-26.py 
# @Software: PyCharm

class Animal():
    def __init__(self, name, age, height):
        self.name = name
        self.age = age
        self.height = height

    def speak(self):
        print('%s:说我的年龄是%d,身高是%s')


class Dog(Animal):
    def __init__(self, name, age, height,sex):
        super().__init__(name, age, height)
        self.sex = sex
    def speak(self):
        print('%s:说我的年龄是%d,身高是%s,我是个%s' % (self.name, self.age, self.height,self.sex))


d = Dog('钢铁侠', 18, 180,'男')
d.speak()

运行结果:

钢铁侠:说我的年龄是18,身高是180,我是个男

super的继承顺序
super是根据mro算法来实现继承顺序

class A():
    def __init__(self):
        print('A')


class B(A):
    def __init__(self):
        super().__init__()
        print('B')


class C(A):
    def __init__(self):
        super().__init__()
        print('C')


class D(B, C):
    def __init__(self):
        super().__init__()
        print('D')


d = D()
print(D.__mro__)

运行结果:

A
C
B
D
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值