Python高级编程(19):python中的序列分类
python中的序列其实就是一种协议,Python是基于协议而开发的。我们依据两个维度来将序列进行分类,一个是按照是否必须存储同一类型分为容器序列和扁平序列;另一个则是序列是否可变,分为:可变序列和不可变序列。
容器序列:list、tuple、deque;扁平序列:str、bytes、bytearray、array.array。
容器序列就是可以存储不同类型数据结构的对象,只是一个容器而已:
12345678a_list = []a_list.append(123)a_list.append("nihao")print(a_list)# 输出结果:[123, 'nihao']
而扁平序列就是只能存储同一数据类型的对象。
可变序列:list, deque,bytearray、array
不可变序列:str、tuple、bytes可变序列就是允许你往里面添加数据,不可变序列就是不允许你修改里面的内容。
Python高级编程(18):contextlib简化上下文管理器
本来我们这个应该是和前面的with语句放在一块的,但是我想多写一篇,目的就是为了突出使用contextlib这个模块以后,我们的上下文管理器简化了很多。
我们还是先来看一段代码:
1234567891011121314151617import contextlib@contextlib.contextmanagerdef file_open(file_name): print("file open") # 此处代码就相当于之前的enter魔法函数实现的代码 yield {} # 必须是yield一个生成器,可以没有{},但是yield关键词必须有 print("file end") # 此处代码就相当于之前的exit魔法函数实现的代码with file_open("envse.txt")as file_read: print("file is reading")# 输出结果:file openfile is readingfile en ...
Python高级编程(17):python中的with语句
要使用 with 语句,首先要明白上下文管理器这一概念。有了上下文管理器,with 语句才能工作。
上下文管理协议(Context Management Protocol):包含方法 __enter__() 和__exit__(),支持该协议的对象要实现这两个方法。
上下文管理器(Context Manager):支持上下文管理协议的对象,这种对象实现了__enter__() 和__exit__()方法。上下文管理器定义执行 with 语句时要建立的运行时上下文,负责执行 with 语句块上下文中的进入与退出操作。通常使用 with 语句调用上下文管理器,也可以通过直接调用其方法来使用。说白了就是你只要是包含了__enter__() 和__exit__()这两个魔法函数,我就可以把你当做一个上下文管理器(鸭子类型)来操作。
我们先来看一段代码,给这个函数实现上下文管理协议:
12345678910111213141516171819class Sample: def __enter__(self): # 获取资源 print("enter&q ...
Python高级编程(16):mixin继承
mixin混合模式的特点:1、mixin类功能单一;2、不和基类关联,可以和任意基类进行组合,基类可以不和mixin关联就能初始化成功;3、在mixin中,不要使用super这种用法;最后尽量以mixin结尾
参考文章:Python mixin模式
Python中的Mixin模式
Python高级编程(15):super真的是调用父类吗?
这一部分非常重要,我相信很多人心中一直觉得super函数就是调用父类,但是结果是这样吗,我们来好好聊一下这个super。我们先来看一段代码:
1234567891011121314class A: def __init__(self): print("A")class B(A): def __init__(self): print("B")if __name__ == '__main__': b = B()# 输出结果:B
这个是没有问题的,很好理解,我们接着来看下一段代码:
12345678910111213class A: def __init__(self): print("A")class B(A): def __init__(self): print("B") super().__init__()# 输出结果:BA
有人说这不就是调用了父类的方法么,我暂且不说话。并向你扔了2个问 ...
Python高级编程(14):python对象的自省机制
自省是通过一定的机制查询到对象的内部结构 ,Python中提供了很多的方法来查询对象的内部结构,比如: hasattr:查询对象是否有一个特性的属性 ;getattr:获取对象的属性 ;setattr:设置对象的属性 ;delattr:从一个对象中删除属性,这些都是比较常规的方法,我们今天主要来讲一下__dict__和dir()这两个方法,我们先来看一段代码:
1234567891011121314151617181920# 自省是通过一定的机制查询到对象的内部结构class Person: name = "user"class Student(Person): def __init__(self, school_name): self.school_name = school_nameif __name__ == '__main__': user = Student("家里蹲大学") # 通过__dict__来查询属性 print(user.__dict__) print(u ...
Python高级编程(13):数据封装和私有属性
在java或者c++里面,我们都有private,protected等来修饰类,从而达到数据封装和私有属性的目的,但是在Python里面,这些都是没有的,那么它是如何达到相同目的的呢?我们继续看段代码:
123456789101112131415161718from .class_method import Dateclass User: def __init__(self, birthday): self.birthday = birthday def get_age(self): return 2018-self.birthday.yearuser = User(Date(1990, 9, 12))print(user.get_age()) # 通过调用这个get_age方法来获取对象的年龄print(user.birthday) # 通过调用这个birthday属性来获取对象的出生信息# 输出结果:281990/9/12
现在我们不希望直接获取到自己的出生信息,需要对其进行隐藏,我们可以使用__birthday(前面有2个下划线)就能实现 ...
Python高级编程(12):类方法、静态方法和实例(对象)方法
定义在类中的代码块叫方法,Python的方法分为『实例方法』、『类方法』、『静态方法』,按照从前到后的顺序它们和实例对象的依赖程度依次降低。
我们先来看一段代码:
12345678910111213141516171819202122class Date: # 构造函数 def __init__(self, year, month, day): self.year = year self.month = month self.day = day def tomorrow(self): self.day += 1 def __str__(self): return "{year}/{month}/{day}".format(year=self.year, month=self.month, day=self.day)if __name__ == '__main__': new_day = ...
Python高级编程(11):类和实例属性的查找顺序—mro查找
我们先来看一段代码:
12345678910111213class A: name = "envse" def __init__(self): self.name = "job"a = A()print(a.name)# 输出结果:job
上面的运行结果是没有任何疑问的,那么我们为啥要专门说明一下这个类和实例的查找顺序呢?那是因为在多继承的条件之下,我们的继承关系就比较复杂了,一眼直接看出来就比较难了。
MRO算法MRO就是method resolution order,主要用于在多继承时判断所调用属性的路径(来自于哪个类)
经典类在Python2.2之前,我们Python里面的类称为经典类,经典类是一种没有继承的类,实例类型都是type类型,如果经典类被作为父类,子类调用父类的构造函数时会出错。这时MRO的方法为DFS(深度优先搜索(子节点顺序:从左到右))
在上面的图里面就是:A–>B–>D–>C–>E。也就是说会先往一条路深了查找,如果找不到就走另一条路。按照这种情况其实是非常合理的,B里 ...
Python高级编程(10):类变量和实例(对象)变量
关于类变量和实例变量,我相信很多小白刚开始学习Python的时候,一直没有搞懂里面初始化代码的意思,也没有哪本书介绍过这里面各个参数的意思,这里看完你就会有一个清醒的认识了。
我们先来看一段代码:
12345678910111213class A: aa =1 # 类变量 def __init__(self, x, y): # 这里的self是指这个类的一个实例化对象,不是类本身 self.x = x # 类实例化后的对象的x等于我们传进来的x (self.x属于我们实例化后的对象,不再属于类本身) self.y = y # 类实例化后的对象的y等于我们传进来的y (self.y属于我们实例化后的对象,不再属于类本身)a = A(2, 4)print(a.x, a.y, a.aa)# 输出结果:2 4 1
这里的a.x 其实就是self.x,a.y其实就是self.y,而这里的a.aa则是类的aa,为什么会这样呢,那是因为这关系到python变量的查找顺序,后面会说。它会首先查找这个实例化对象是否存在aa这个属性,如果不存在就往 ...
