Python知识点整理(1) —— 语言基础

Python语言基础

Note: This blog is created to Prepare For Intern Interviews

python语言特性

静态or动态?强类型or弱类型?

  • 动态强类型语言
  • 动态or静态:编译期还是运行期确定类型
    • 动态:没有类型申明
  • 强类型:不会发生隐式类型转换
    • JS, PHP就是弱类型(eg. 数字和字符串可以相加)

Python作为后端语言优缺点

  • 轮子多,胶水语言,应用广泛
  • 语言灵活
  • 性能问题、代码维护问题、python2/3兼容问题

鸭子类型

  • 关注点在对象的行为,而不是类型(duck typing)
  • file/stringio/socket对象都支持read/write方法
  • 定义了__iter__魔术方法的对象可以用for迭代
  • 更关注接口(方法)而不是类型

monkey patch

  • 运行时的属性替换
  • e.g. gavent库修改内置的socket(堵塞变成非阻塞)

自省(introspection)

  • 运行时判断一个对象类型的能力
  • 一切皆对象,用type,id,isinstance来获取对象类型信息
  • inspect模块提供了更度获取对象信息的函数

列表&字典推导

  • list comprehension
    • 快速生成list/dict/set的方式。用来替代map/filter等
    • ( i for i in range(10) if i % 2 == 0)返回生成器可以大大节省内存
  • 可以简化操作:
a = ['a', 'b', 'c']
b = [1, 2, 3]
d = {k: v for k, v in zip(a,b)}

python之禅

  • import this
  • 动态语言编写大型项目的时候维护性差,重构很难

python2/3差异

python2/3差异

  • pyenv支持本地装多个python版本
  • python3改进
    • 类型注解(type hint),帮助IDE实现类型检查。e.g. def f(name:str) -> str:
    • 优化的super()方便直接调用父类函数 e.g. python2: super(<子类名>, self).f(), python3: super().f()
    • 高级解包操作。a, b, *c = range(10)–> a = 0, b = 1, c = [2,3, ..., 9]
    • 编码问题。python2默认总结,python3不再有unicode对象,默认str就是unicode。做传输的时候,需要把unicode encode成字节串,当拿到字节串的时候要decode成unicode。
    • 除法变化:‘/’结果是浮点数,要用‘//’ 才能做一个截断
    • from future import print_function
    • print成为函数:print (?) print ('a', 'b', sep = '|'). >>> a|b
    • 限定关键字参数:def f(a, b, *, c)(*后面的必须要传递名字)
    • 一切返回迭代器 range,zip,map,dict.values, etc. (e.g. range()返回可迭代对象,不会立马生成列表)
    • chained exceptions:有利于排错。原来:从一个异常里面再raise一个异常,原来的异常就会丢失。
    • 生成的pyc文件统一放到一个文件中
    • 内置库的修改 urllib, selector等
    • 性能优化

python3新增

  • yield from 链接子生成器
  • asyncio内置库,async/await 原生协程支持异步编程
  • 新的内置库 enum, mock, asyncio, ipaddress, concurrent.futures 等

python2/3工具

  • six模块
  • 2to3等工具
  • __future__

python函数常考

python传递参数

  • 共享传参(call by sharing)
  • 形参和实参都是指向对象
  • 不可变(拷贝)/可变(引用)对象
    • 不可变对象:bool/int/float/tuple/str/frozenset
    • 可变对象list/set/dict

【例题】输出结果是什么?

def f(l):
    l = []
    print ('l:', l)
    print (id(l))
ll = [1,2]
f(ll)
print ('ll:',ll)
print (id(ll))

l: []
4491653000
ll: [1, 2]
4491652936

【例题】python可变参数作为默认参数,结果是什么?

def f(l=[1]):
    l.append(1)
    print (l)
f()
f()

[1, 1]
[1, 1, 1]

原因:默认参数只计算一次(参考文档:https://www.cnblogs.com/zwgblog/p/7194950.html)

*args, **kwargs

  • 用来处理可变参数(参数个数不确定)
  • *arg(可变的参数)被打包成tuple
  • **kwargs(可变的关键字参数) 被打包成dict
  • 传参方式
    • 直接传递
    • 用一个*打包,传list
    • 使用两个*打包,传dict

Python异常机制

python使用异常处理错误

  • BaseException(所有都继承这个异常)
  • SystemExit
  • KeyboardInterrupt
  • GeneratorExit
  • exception
    • 自定义的时候都是继承这个类

异常常见的场景

  • 网络请求(超时、连接错误)
  • 资源访问(权限、资源不存在)
  • 代码逻辑(越界访问、keyerror)
try:
	# func								# 可能会抛出异常的代码
except (Exception1, Exception2) as e 	# 可以捕获多个异常处理
	# 异常处理代码
else:
	# pass								# 异常没有发生的时候代码逻辑
finally:
	# pass								# 无论异常有没有发生都会执行的代码,一般处理资源的关闭和释放		

自定义异常

  • 继承exception实现自定义异常(为什么不是BaseException? control-c就不能终止了)
  • 给异常加上一些附加信息
  • 自定义:raise(myexception)

python性能分析与优化(GIL)

GIL(global interpreter lock)

  • cpython解释器的内存管理并不是线程安全
  • 保护多线程情况下对python对象的访问
  • cpython使用锁机制避免多线程同时执行字节码

gil影响:限制了程序的多核执行

  • 同一时间只能有一个线程执行字节码
  • cpu密集程序难以利用多核优势
  • io期间会释放GIL, 对IO密集程序影响不大

规避gil影响:区分cpu还是io密集

  • cpu密集:大量时间花在计算上,多进程+进程池
  • io密集:大量时间花在传输上,使用多线程/协程
  • cython扩展(python转成c++)

为什么有了gil还要关注线程安全

  • 一个操作如果是一个字节码指令可以完成的就是原子
  • 原子的是可以保证线程安全的
  • 使用dis操作来分析字节码
  • 编码:lock = thread.lock()with lock

如何剖析程序性能:使用profile工具

  • 二八定律,大部分时间耗时在少量代码
  • 内置的profele工具
  • 使用pyflame的火焰图工具

服务端性能优化措施
web应用一般语言不会成为瓶颈

  • 数据结构&算法
  • 数据库层:索引优化、慢查询、nosql、批量操作减少io
  • 网络io:批量操作、pipeline操作、减少io
  • 缓存:使用内存数据库 redis/memcached
  • 异步:asyncio,celery。异步编程就是把耗时的操作放进一个单独的线程中进行处理(该线程需要将执行进度反映到界面上)。由于耗时操作是在另外一个线程中被执行的,所以它不会堵塞主线程。主线程开启这些单独的线程后,还可以继续执行其他操作(例如窗体绘制等);异步编程可以提高用户体验,避免在进行耗时操作时让用户看到程序“卡死”的现象)
  • 并发:gevent/多线程

python生成器与协程

生成器 generator

  • 可以生成值的函数
  • 当函数里有yield关键字
  • 可以挂起执行,并产出数据

基于生成器的协程

  • pep342 增强生成器功能
  • 生成器可以通过yield暂停执行和产出数据
  • 同时支持send()向生成器发送数据和throw()向生成器抛出异常

协程

  • 需要send或者next来预激才能启动(可以使用协程装饰器避免每次都要用send预激他)
  • 在yield处协程会暂停执行
  • python3.5引入async/await支持原生协程(native coroutine)

python单元测试(unit testing)

  • 动态语言需要python的单元测试来保证代码质量
  • 针对程序模块进行正确性
  • 一个函数,一个类进行验证
  • 自底而上

防止三无代码(文档、注释、单测)

  • 保证代码逻辑正确性(甚至测试驱动开发tdd)
  • 易测的代码往往是高内聚低耦合的
  • 回归测试防止改一处导致整个服务不可用

单元测试的库

  • nose/pytest
  • mock模块来模拟替换网络请求等
  • coverage统计测试覆盖

设计测试用例

  • 正常值
  • 边界值
  • 异常值(非法、none、空值等)

python深拷贝&浅拷贝

  • 深拷贝:a = b;两者的值不受影响
  • 浅拷贝:a = b;b的值变了,a也变了
  • 初始化二维数组:
    • 给数组的内容赋值,而不是一个数组a = 数组b这样的赋值方法
    • deep_copy

详细介绍: https://www.cnblogs.com/xueli/p/4952063.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值