Python高级

Python进阶

1python一切皆对象

函数 类 模块 代码本身都是对象,python灵活建立在一切皆对象。

类是模板对象,用来生成实例对象

既然类是对象,那么就可以动态的修改他的属性

2:type  class  object的关系

type(1)--->int

type(int)--->type

type--->int--->1其他类型一样

type--->class---->obj

object是所有类的顶层基类

type本身是一个类,同时也是一个对象,type的父类是object

type(object)---->type 好像成了一个闭环?

type和object的关系混乱? 

3 魔法函数

 魔法函数可以加在类里面增强类的类型

1:不能自己创建新的魔法方法,不用继承任何类,任何类里面都可以定义魔法函数,类有了魔法函数就有了一些特性。

2:不需要自己调用,python解释器会在我们使用语法或对应函数时隐式调用,你只需要在对应的类中定义即可

3:魔法函数会影响到python语法本身,还有python的内置函数

熟悉了魔法函数,设计类的时候就会更加灵活,还能看懂源码,以及人家为什么这么设计。

鸭子类型:长得像鸭子就是鸭子;在与魔法函数结合起来,python的灵魂所在

class Students:
    
    def __init__(self, stu_list):
        self.stus = stu_list
stu = Students(["zhangsan","lisi","wangwu"])
stus = stu.stus
for stu in stus:
    print(stu)

  

class Students:
    
    def __init__(self, stu_list):
        self.stus = stu_list

    def __getitem__(self, item):
        return self.stus[item]
stus = Students(["zhangsan","lisi","wangwu"])

for stu in stus:
    print(stu)

 加入了魔法方法__getitem__就可以直接遍历创建出来的对象,for循环去找去找getitem方法,直到抛出异常,此时还可以切片。

魔法函数加python语法,体现了python的灵活性,写起来十分的简单,只要你熟悉了魔法函数。

魔法函数详解

 4:鸭子类型

看源码的时候,有的规定参数的类型是itraeble,并不是说必须是继承这个类,而是说属于这类鸭子

这里的类型指的是实现了某魔法函数的类创建的对象。

此时你可以实现一个类满足了iterable的协议就可以,那么这个类也可以传进来

对比java,参数类型是提前定义好的,这点python动态语言十分灵活。

只要在类里面定义了魔法方法,那么这个类就是一个大类别。python充分利用了鸭子类型。

数据类型上面有一个大的类型,用的是魔法方法进行的分类。

5:抽象基类

abc模块,视为java里面的接口,接口不能实例化,abc模块里面的类同样不能实例化

python是动态语言,没有变量类型一说,python中变量只是一个符号而已,可以指向任何类型的对象,所以python中没有多态的概念

可以赋值任何数据给python中的变量,而且是可以修改的。因此不需要像java那样刻意的实现多态,因为python诞生之初就是多态

动态语言没有变量类型,因此少了编译时检查错误的环境。运行起来才会发现错误,这是动态语言的共同缺陷,无法做类型检查

python崇尚鸭子类型,贯穿python的面向对象,使用类型和设计类型时应把鸭子类型放在第一位

实现约定好的魔法函数视为协议

抽象基类:1 无法实例化 

     2基础类设定了方法,所有继承抽象基类的类都必须覆盖里面的抽象方法

python已经有了鸭子类型的设计,为什么要有抽象基类呢,直接实现某些方法不就行了么。

场景1:检查某个类是否有某种方法,比如说别人写了一个类,里面有__len__(),但是暂时你不知道,怎么检查呢?

  提供了反射即使hasattr(类名,“属性名”)按照结果判断;但是很少用反射,更多的是判断是否是某种类型,用isinstance(stu,Iterable),而非hasattr(stu,"__iter__")

所以如果没有抽象基类,就要用hasattr的方式来判断类型

场景二:强制约束某个子类必须实现某些方法

如web框架中的组件就是抽象的,子组件是满足不同需求但是接口相同的类。

总结:python已经实现了一些通用的抽象基类,让我们可以了解python的数据结构的一些接口,在collections.abc模块下

这些抽象基类里面只放一个抽象方法,每个都有一个魔法函数,用@classmethod修饰,__subclasshook__(cls,C)

isinstance(stu,Sized),Student没有继承Sizde居然能判断出是不是这个大类

每个抽象类里面都配了这么个方法,背后本质帮你检查有没有这个魔法方法名的属性,还会尝试类的继承链;而type(stu)只能显示Student,无法显示SIzed

实际使用时很少去继承抽象基类,更多的是使用鸭子类型。

更多的是使用mixin,混合模式,一个类继承多个类,但是父类不和基类有任何关联;每个mixin类只实现一个方法,功能单一;不和基类关联,不要在mixin中使用super

6:with

和try except一起使用的时候,finally中有return,except中有return,return的结果会压入栈中

最后return的是栈顶的。

with上下文管理器,涉及到两个协议__enter__和__exit__

with会调用__enter__,结束自动调用__exit__(),不一定非是操作文件的时候使用with

任何一个类都可以 with Student() as stu:

            stu.say()

6.2对于函数也可以适应上下文管理器,python提供了contextlib模块,巧妙的利用了生成器的特性,yield前是enter,yield后是exit

 7:array效率高于list

当明确知道存放一种数据的时候用array

import array

arrays = array.array("i")   # 参数指的是那种类型

8:元类编程

type负责创建所有类

__new__(cls, *args, **kwargs):创建实例对象之前调用的逻辑

__init__(self):生成实例对象之后,对对象做的事,主要用来完善实例对象

看十遍不如自己写一遍!巩固基础,纵横开拓!
原文地址:https://www.cnblogs.com/gyxpy/p/12855537.html