- 1. 装饰器(给函数增加功能)
# 多个装饰器的装饰过程就是:离函数最近的装饰器先装饰,然后外面的装饰器再进行装饰,由内到外的装饰过程
def test_a(func):
def test_b():
return func
return test
@test
def func():
pass
# @类装饰器名:等价于“函数引用 = 类名(函数引用)”,所以需要提供一个__init__方法,并多增加一个fn参数。
# 在__call__方法里进行对fn函数的装饰,可以添加额外的功能。
class 类装饰器名(obj):
def __init__(self, 引用):
self.func = 原函数引用
def __call__:
# 扩展方法
self.func(*var, **kwvar) # 执行原函数
# 扩展方法
- 2. 上下文管理器(执行过程是先执行魔法方法enter, 然后执行with内的函数语句,最后执行exit魔法方法)
# 上下文管理器
# 使用with 可以使代码更简洁
with open('test.txt', 'w') as f:
f.write('Python')
# 上下文管理器的执行过程
# 自定义一个上下文管理器,模拟with文件操作
class MyOpen(object):
def __init__(self,path,mode):
# 记录要操作的文件路径和模式
self.__path = path
self.__mode = mode
def __enter__(self):
print('代码执行到了__enter__......')
# 打开文件
self.__handle = open(self.__path,self.__mode)
# 返回打开的文件对象引用, 用来给 as 后的变量f赋值
return self.__handle
# 退出方法中,用来实现善后处理工作
def __exit__(self, exc_type, exc_val, exc_tb):
print('代码执行到了__exit__......')
self.__handle.close()
# a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
with MyOpen('test.txt','a+') as f:
# 创建写入文件
f.write("Hello Python!!!")
print("文件写入成功")
- 3. 进程锁
场景描述,多个请求过来,有一个表字段递增,所以每次仅允许同时处理一个请求,所以需要进程锁,来释放和保护进程。
# Python守护进程、进程互斥锁、进程间通信ICP(Queue队列)、生产者消费者模型
# 上面知识点会另起一片blog介绍
from multiprocessing import Process, Lock
def f(l, i):
l.acquire() #锁住进程
try:
print('hello world', i)
finally:
l.release() #释放锁
if __name__ == '__main__':
lock = Lock()
for num in range(10):
Process(target=f, args=(lock, num)).start()
- 4. 排序算法
# 冒泡排序
# 冒泡排序时间复杂度On2/先假设a[0]最小,遍历后面元素,有小的则替换,依次确定a[2]~a[n]的数据
def bubble_sort(arr):
for i in range(1, len(arr)):
for j in range(0, len(arr)-i):
if arr[j] > arr[j+1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
return arr
# 快速排序:
# 利用空间换时间,假设a[0]最小,a[n]最大,一直到确定所有元素位置
def quick(li, left, right):
if left < right: # 如果左索引<右索引
mid = part(li, left, right) # 调用part进行分区 返回一个索引赋给mid
quick(li, left, mid - 1) # 递归调用quick 直到left=mid-1
quick(li, mid + 1, right) # 递归调用quick 直到mid+1=right
li = list(range(1000))
quick(li, 0, len(li) - 1)
print(li)
- 5. 使用python创建一个栈
# 栈 先进后出。
class Stack(obj): #构造函数
def __init__(self):
self.values = []
def push(self, value): # 新数据
self.values.append(value)
def pop(self): # 抛出(返回)栈鼎数据
return self.values.pop()
def is_empty(self): #空栈测试,返回布尔
return self.size() == 0
def size(self): # 返回栈内数目
return len(self.values)
def peak(self): # 返回栈鼎数据,但不删除
return self.values[self.size()-1]
- 6. yield
迭代器:yield 的好处是迭代能力,比起用类的实例保存状态来计算下一个 next() 的值要简洁的多.
而且对象的保存,不会执行任何函数代码,直到对其调用next()方法才开始执行。
return返回值,在第一次调用函数,yield返回迭代对象;
- 7. 判断两个字符串是不是换位字符串
# # 判断两个字符串是不是换位字符串
# 将存在字符和数量存储到字典中
# 判断字典是否相等
def test(test_str):
c = []
d = {}
for i in range(0, len(test_str)):
if a[i - 1] not in c:
c.append(i)
d[test_str[i-1]] = 1
else:
d[test_str[i-1]] += 1
return d
if __name__ == '__main__':
a = "aaaabbc"
b = "abcbaaa"
hash_str1 = test(a)
hash_str2 = test(b)
print(hash_str1,hash_str2)
if hash_str1 == hash_str2:
print('True')
else:
print('False')
- 8. 匿名函数
$ sum = lambda i,j:i+j
$ print(sum(22,33))
$ 55
- 9.单例模式
确保某一个类只有一个实例,而且自行实例化并向实例化并向整个系统提供这个实例,这个称为单例类,单例模式是一种对象创建型模型。
# 实例化一个单例
class Singleton(object):
__instance = None
def __new__(cls, age, name):
#如果类属性__instance的值为None,
#那么就创建一个对象,并且赋值为这个对象的引用,保证下次调用这个方法时
#能够知道之前已经创建过对象了,这样就保证了只有1个对象
if not cls.__instance:
cls.__instance = object.__new__(cls)
return cls.__instance
a = Singleton(18, "dongGe")
b = Singleton(8, "dongGe")
print(id(a)) print(id(b))
a.age = 19 #给a指向的对象添加一个属性
print(b.age)#获取b指向的对象的age属性
- 10.python 的内存管理及垃圾回收
import sys
sys.getsizeof("") # 49
sys.getsizeof([]) # 64
sys.getsizeof(()) # 48
sys.getsizeof(set()) # 224
sys.getsizeof(dict()) # 240
# 作为参照
sys.getsizeof(1) # 28
sys.getsizeof(True) # 28
sys.getsizeof([1,2,3]) # 88
[1,2,3].clear() # 清空后64,即[]
sys.getsizeof({1,2,3}) # 224
{1,2,3}.clear() # 清空后224,即set()
sys.getsizeof({'a':1,'b':2,'c':3}) # 240
{'a':1,'b':2,'c':3}.clear() # 清空后72{},即dict()
见 这里 ? https://blog.csdn.net/zzy_zatan/article/details/100018480
- 11. GIL锁
全局解释器锁?
对于有io操作的线程,当一个线程在做io操作的时候,
因为io操作不需要cpu,所以,这个时候,python会释放python全局锁,
这样其他需要运行的线程就会使用该锁。
对于cpu密集型的线程,比如一个线程可能一直需要使用cpu做计算,
那么python中会有一个执行指令的计数器,当一个线程执行了一定数量的指令时,
该线程就会停止执行并让出当前的锁,这样其他的线程就可以执行代码了。
由上面可知,至少有两种情况python会做线程切换,一是一但有IO操作时,
会有线程切换,二是当一个线程连续执行了一定数量的指令时,会出现线程切换。
当然此处的线程切换不一定就一定会切换到其他线程执行,因为如果当前线程
优先级比较高的话,可能在让出锁以后,又继续获得锁,并优先执行。
- 12. if _name__ = "__main__"的理解
##存为if__name.py
def main():##必须定义为main()不能为其他字符表示。
print("hello world %s"%__name__)
if __name__=='__main__':##目的对于调用该文件的其他文件来说确保,该文件的方法
##只执行一次。这样就是本身也可以执行,其他文件调用它而不至于执行两次。
main()##在改文件内if会满足,而其他文件调用时,不会满足if。
##存为main__name.py
import if__name
if__name.main()##得到
##hello world if__name,说明__name__为'if__name',从而不会执行被引用文件的if判断下的语句。目的避免执行被引用文件两次
- 13.深拷贝和浅拷贝
a = 1
b = a # 赋值是浅拷贝
# 对于list、dict、set等数据而言
a = [11,22,33]
import copy
c = copy.copy(a) # 浅拷贝:值不变,内存地址改变
d = copy.deepcopy(a) # 深拷贝:值不变,内存地址改变