学习分享:python语言(持续更新)

01 函数传参

python一切皆对象,分为2类:
(1)num,str,tuple 不可更改
(2)list,dict,set 可更改
函数传参时,传的是引用,第一类不会变,第二类会变

02 类&对象&静态方法

python有3个方法:
(1)实例方法
self 绑定实例——》foo(self,x)
(2)类方法
cls 绑定类——》class_foo(cls,x)
(3)静态方法
不需要绑定——》 classname(objectname).func
A.static_foo(x) a.static_foo(x)

03 类&对象变量

实例变量:只属于单个实例——》self.变量名
类变量:对于所有实例是共享的——》classname.var

04 自省

在运行时,能知道对象类型

  • type() :返回对象类型(不考虑继承)
    在这里插入图片描述
  • dir() :返回模块的变量、方法和定义的类型列表
  • getattr(对象,属性) :返回对象属性的值
  • hasattr(对象,属性) :检查对象是否有属性值
  • isinstance(对象,类型) :检查对象是否是该类型(考虑继承)
    在这里插入图片描述
    inspect模块
    在这里插入图片描述

05 推导式

(1)字典推导式
d = {k:v for k,v in zip(list1,list2)}

快速对换键,值对
在这里插入图片描述
(2)集合推导式
在这里插入图片描述
和列表推导式,最大的不同,用大括号

06 下划线

单前导下划线:_var                        # 半私有,可被外部访问
单末尾下划线:var_                        # 避免命名冲突
双前导下划线:__var                        # 私有,不可以被外部访问
双前导和末尾下划线:__var__       # 魔术方法,内置属性名
单下划线:_                                    # 临时/无关紧要的变量

私有 self.__head = None
双下划线:解析器用_classname__fuc区分和其他类相同的命名

07 可迭代对象 VS 迭代器 VS 生成器

在这里插入图片描述

(1)可迭代对象:
有__iter__()方法
如:str,list,tuple,set,dict
(2)迭代器
有__iter__()方法 和 next()方法
迭代结束,跑出StopIteration异常
(3)生成器
有yield,iter()方法 和 next()方法
可以从外部用send给yield传值

用iter()函数,可以将可迭代对象转为迭代器

return和yield的区别: 都可以返回1个/多个值 return返回1次,yield返回多次

  • 迭代器:存储的 ,可循环多次,用next(i)遍历,超出范围则抛出异常
li =  [x*x for x in range(10)]     # li是可迭代对象(iter)
i = itr([x*x for x in range(10)])  # i是迭代器对象(iter,next)
  • 生成器(特殊迭代器):实时的,只能循环1次
g = (x*x for x in range(10))

iter()
对可迭代对象,返回其迭代器的实例
对迭代器,返回自身self

class MyList(object):           
	## 定义可迭代对象类  
    def __init__(self, num):  
        self.data = num          # 上边界  
 
    def __iter__(self):  
        return MyListIterator(self.data)  # 返回该可迭代对象的迭代器类的实例  
   
class MyListIterator(object):   
	## 定义迭代器类,是MyList可迭代对象的迭代器类  
    def __init__(self, data):  
        self.data = data         # 上边界  
        self.now = 0             # 当前迭代值,初始为0  
  
    def __iter__(self):  
        return self              # 返回该对象的迭代器类的实例;因为自己就是迭代器,所以返回self  
  
    def next(self):              # 迭代器类必须实现的方法  
        while self.now < self.data:  
            self.now += 1  
            return self.now - 1  # 返回当前迭代值  
        raise StopIteration      # 超出上边界,抛出异常  
  
my_list = MyList(5)              # 得到一个可迭代对象  
print type(my_list)              # 返回该对象的类型  

my_list_iter = iter(my_list)     # 得到该对象的迭代器实例  
print type(my_list_iter)  
 
for i in my_list:                # 迭代  
    print i  

## 定义生成器 
def myList(num):       
    now = 0           # 当前迭代值,初始为0  
    while now < num:  
        val = (yield now)     # 返回当前迭代值,并接受可能的send发送值,yield可以理解为不释放函数的return
        now = now + 1 if val is None else val  # val为None,迭代值自增1,否则重新设定当前迭代值为val  
  
my_list = myList(5)   # 得到一个生成器对象  
  
print my_list.next()  # 返回当前迭代值  
print my_list.next()  
  
my_list.send(3)       # 重新设定当前的迭代值  
print my_list.next()    
print dir(my_list)    # 返回该对象所拥有的方法名,可以看到__iter__与next在其中  

https://blog.csdn.net/liangjisheng/article/details/79776008

08 枚举enumerate

for idx,val in enumerate(li):
	print(idx,val)

在这里插入图片描述

09 *args&*kwargs

*args:参数数量不定(列表)
**kwargs:参数名不定(字典)

*args必须在**kwargs前面

li = [1,2,3]
func(*li )解释器自动解包,传入多个参数《——》func(1,2,3)

10 装饰器(decorator)

为已存在的对象,添加额外的功能

将函数func作为参数,传给另一个函数,返回修改后的自己
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

应用场景:插入日志、性能测试、事务处理
https://www.runoob.com/w3cnote/python-func-decorators.html

斐波那契记忆化递归写法:

def memo(func):
	cache = {}
	def wrap(*args):
		if args not in cache:
			cache[args] = func(*args)
		return cache[args]
	return wrap
@memo
def fib(n):
	if n<2:
		return 1
	return fib(n-1)+fib(n-2)

11 鸭子类型(像=是)

行为像鸭子,就认为它是鸭子
list.extend(鸭子):这个鸭子可以是list,tuple,dict,str,generator等可迭代的

12 函数重载

(i)函数功能相同,(ii)参数类型不同,(iii)参数个数不同。
(i)+(ii):不需要处理(python可接受任何类型参数)
(i)+(iii):缺省函数(缺少的参数设成缺省参数)
因此,python不需要函数重载

13 新式类&旧式类

  • 新式类: 从左到右,宽度优先 (C3算法)
  • 旧式类: 从左到右,深度优先 (子类重写,会被绕过)
    (子类越过父类,子类重写父类构造——》报错)

继承object的是新式类

14 new vs init

  • new创建对象,init初始化对象
  • new返回对象,init无返回
  • new的调用在init之前,是静态方法
  • new是类级别的(至少有个参数cls),init是对象级别的(至少有个参数self)

cls表示要实例化的类

__new__
__init__
  • new的应用:
    继承不可改变类时,重载new,自定义以改变对象实例化过程

15 单例模式(面试常考)

类只有一个对象
创建单例时,只执行1次init方法

class Singleton(object):
	__instance = None  # 私有属性
	def __new__(cls,age,name):
		if not cls.__instance: # 无类对象,或类对象无值
		cls.__instance = object.__new__(cls) # 创建对象,赋值为对象的引用
		return cls.__instance # 如果有,就直接返回
	def __init__(self,age,name):
		if not self.__first_init:
			self.age = age
			self.name = name
			Singleton.__first_init = True
			
a = Singleton(18,"xxx")
b = Singleton(8,"xxx")
print(id(a),id(b)) #两个id是一样的
print (a.age,b.age) # a,b指向的对象属性一样
a.age = 19
print(b.age)  # b指向的对象属性和a一样

(1)使用new方法
(2)共享属性
创建对象时,把所有对象的__dict__指向同一个字典
对象具有相同的属性和方法
(3)装饰器版本
(4)import方法
import的模块是天然单例模式

作用:节约系统资源
应用:回收站

16 作用域

  • 变量作用域:在被赋值的地方决定
  • 遇到变量,搜索顺序:
    local——》enclosing locals——》gloabl——》built-in

local:本地作用域
enclosing locals:当前作用域被嵌入的,本地作用域
gloabl:全局/模块作用域
built-in:内置作用域

global:在函数中,使用全局变量
nonlocal:在内嵌函数中,使用外部函数的变量

17 协程

进程、线程的升级版

进程&线程:内核态,用户态切换问题,耗费时间
协程:用户控制切换时机,不陷入内核态

yeld是协程

在这里插入图片描述

18 闭包(closure)

语法结构,组织代码的结构,提高复用性
产生条件:
(1)内嵌函数
(2)内嵌函数引用外部函数的变量
(3)外部函数返回值是内嵌函数
函数运行后,不能被销毁,继续留在内存

19 lambda

==lambda表达式=匿名函数 ==
在这里插入图片描述

lambda 输入:输出
lambda x : x**2
lambda x,y : x+y

在这里插入图片描述
在这里插入图片描述

20 函数式编程(filter,map,reduce)

  • filter:过滤器,只留下满足filter条件的
filter(lambda x : x>1, [1,2,3])      # 返回[2,3]
  • map:对序列依次执行
map(lambda x: x*2, [1,2,3])      # 返回[2,4,6]
  • reduce:对序列依次迭代调用
reduce(lambda x,y : x+y, [1,2,3])     # 返回1+2+3=6

其中[1,2,3]可以换成range(1,4)

21 浅拷贝&深拷贝

列表是可变类型

原始列表:
li = [1,2,3,[‘a’,‘b’]]

改变列表:
li.append(100) # 改变对象li
li[3].append(‘c’) # 改变对象li的list对象[‘a’,‘b’]

最终列表:
li = [1,2,3,[‘a’,‘b’,‘c’],100]

  • 赋值:完全相同,跟着变
    li2 = li
    li2 = [1,2,3,[‘a’,‘b’,‘c’],100]

  • 浅拷贝:部分相同,只能变对象的对象
    li3 = copy.copy(li)
    li3 = [1,2,3,[‘a’,‘b’,‘c’]]

  • 深拷贝:完全不同,不会变
    li4 = copy.deepcopy(li)
    li4 = [1,2,3,[‘a’,‘b’]]

22 整数范围

-2147483648 < int < 2147483648
长整数:25L

23 垃圾回收机制

引用计数+分代回收。引用计数为主。
原理:每一个对象都记住有多少其他对象引用了自己,当没有人引用自己的时候,就是垃圾了。

  • 引用计数(reference counting):跟踪和回收垃圾
    对象有新引用,ob_refcnt + 1
    对象被删除,ob_refcnt - 1
    ob_refcnt = 0,对象生命结束
    简单,实时;维护ob_refcnt 消耗资源,循环引用

  • 标记-清除(mark and sweep):解决容器对象可能产生的循环引用问题
    按需分配
    没空闲内存,从寄存器和程序栈上的引用出发,遍历图(节点=对象,引用=边),可访问的标记,清扫内存,没标记的对象释放

  • 分代回收(generation collection):空间换时间,提高回收效率
    内存块按存活时间划分到不同集合(代)
    代存活时间越长,垃圾收集频率越低
    默认定义3代

24 is

is:对比地址
==:对比值

25 read & readline & readlines

read:读整个文件
readline:读下一行,用生成器
readlines:读整个文件,放入迭代器

26 range & xrange

range:返回list,数据全部生成取出,存在内存中
返回一个list,是可迭代对象,不是迭代器
经过iter()可转为列表迭代器

xrange:生成器,数据生成一个取出一个,内存性能更好
返回一个序列,是可迭代对象,不是迭代器
经过iter()可转为范围迭代,用next()取出

python3只有range() 和python2中的xrange一样

27 python2 VS python3

python2.7和python3.x的区别

28 list

python的list

29 超类super

重写:继承机制,构造方法
构造方法:初始化对象的状态
子类:自己的初始化+超类的初始化(绝大多数)

一个类的构造函数被重写,就要调用超类构造方法,否则会错误初始化

super在新式类中使用
代码块前加:

__metaclass__ = type

重写基类构造函数时:

super(derived_class,self).__init__()

即使类已继承多个超类,只需用1次super函数
python2.7中的super方法

30 eval()

返回字符串表达式的值

str = ‘[1,2,3]’
s = eval(str)   
# Output: [1,2,3]

31 内核态 & 用户态

操作系统的两种CPU状态

  • 内核态:运行,操作系统,程序
    运行在R0特权级
    进程能访问:所有的内存空间和对象,处理器不可被抢占

  • 用户态:运行,用户,程序
    运行在R3级(最低)特权级以上
    进程能访问:有限的内存空间和对象,处理器可被抢占

  • 内核态—>用户态:
    设置程序状态字PSW

  • 用户态—>内核态:
    系统调用,异常,外围设备的中断,陷入机制(访管指令)

32 各种锁

全局解释器锁(GIL)

gloal interpreter lock 保证线程安全
python解释器中的bool值,受互斥保护。

1CPU,同时,运行1线程
多线程,存在资源竞争,GIL保证线程唯一使用共享资源(cpu)

优点:
(1)避免加锁、解锁
(2)数据安全,多线程数据完整、状态同步

缺点:多核退化成单核,只能并发,不能并行

  • io密集型任务:用多线程(资源调度)
  • cpu密集型任务:用不着多线程,反而可能资源争夺,变慢
    用多进程(资源分配),协程

同步锁

线程运行过程,出现i/o操作,cpu可能切换到别的线程,影响程序完整执行

在公共数据前后加:上锁、释放锁操作

保证,解释器级别下,程序唯一使用共享资源

递归锁

同一线程,多次请求,同一资源

RLock:可重入锁(Lock+Counter)
Counter记录请求次数,直到所有acquire被释放,其他线程才能获得资源

分为:可递归,非递归

乐观锁 & 悲观锁

  • 乐观锁:
    假设不会发生,并发冲突
    只在提交操作时,检查是否违反数据完整性

  • 悲观锁:
    假设一定会发生,并发冲突
    屏蔽一切可能违反数据完整性的操作

死锁

  • 现象:2个及以上,进程/线程,执行过程,争夺资源,相互等待
  • 原因:进程资源竞争,资源分配不当,推进顺序不当
  • 产生条件:互斥,请求和保持,不剥夺,环路
  • 避免方法:银行家算法
  • 预防方法:摒弃产生条件的(2)-(4)
  • 检测方法:资源分配图
  • 解除方法:剥夺资源,撤销进程

python加锁方式

互斥锁,可重入锁,迭代死锁,互相调用死锁,自旋锁

33 python运行过程

解释型脚本语言
运行过程如下:
(1)虚拟机,读入py文件
(2)词法分析,编译成opcode(虚拟机认识的代码)
(3)虚拟机,解释opcode
最后一步非常慢,需要先将opcode编译成中间代码,再翻译成CPU可理解的指令

34 魔法

__slots__魔法,可以将内存占用率减少40%~50%
在这里插入图片描述

45 collections

(1)collections.defaultdict(int)
不需要检查是否有key存在
(2)collections.Counter(var)
以key,val的方式输出每个var出现的次数
(3)collections.deque()
创建双端队列
右边(队尾)添:d.append() ; d.extend()
右边(对尾)删:d.pop()
左边(队首)添:d.appendleft(); d.extendleft()
左边(队首)删:d.popleft()
限制队列大小:d= deque(maxlen=30)
在这里插入图片描述
(4)collections.namedtuple

46 异常

try:
可能异常的语句
except:
处理异常的代码
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

47 跳出双重循环

else在循环正常结束时执行
如果内层循环,是由于break中断,则跳过else语句,执行break
在这里插入图片描述
找2~9之间的质数:
在这里插入图片描述

48 检查对象的内存占用情况

sys.getsizeof(object)

import sys
mylist = range(0, 10000) 
print(sys.getsizeof(mylist))
# 48

range函数返回的是一个类对象,它表现为一个列表,因此使用range函数比使用实际的包含一万个数字的列表要更加节省内存。

参考

https://github.com/taizilongxu/interview_python
https://www.cnblogs.com/gizing/p/10925286.html
https://blog.csdn.net/chinesehuazhou2/article/details/90746215
https://www.jiqizhixin.com/articles/2020-02-06?from=synced&keyword=%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E6%8A%80%E5%B7%A7

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值