赞
踩
python 是动态强类型语言:
背景:
动态/静态:运行时确定变量类型/编译时确定变量类型
强/弱 类型:不会/会 发生隐式类型转换 (例如:int(3.14)=3;int+str类型不能进行运算)
(1)语法和表达方式简单灵活,开发效率高(像写英文)
(2)属于胶水语言,有很多前人(c、python、java)的库(轮子)
(3)需要解释器转换,执行效率低,性能不如其他语言
(4)是动态语言,没有类型声明时就没有自动补全,很多问题要运行后才能发现(维护麻烦,兼容问题)
一切皆对象得含义就是每一个都有自己得属性,每一个都有自己得继承关系,你看到没有继承得,其实它隐式继承了object或者type。关于type可以看看元类。是对象意味着它可以随时随地得使用,比如赋值给一个变量,添加到列表中,作为参数出传递,做返回值。
当看到一只鸟走起来想鸭子、有用起来像鸭子、叫起来也想鸭子、那么这只鸟就可以被称为鸭子
(1)关注点在对象的行为,而不是类型(duck typing)
(2)只要实现了某种接口方法就行,而不在乎是什么类型,比如 file、StringIO,socket对象都支持read/write方法(file like object)
(3)在比如定义了 __iter__
魔法方法的类实例对象都可以用for来迭代
所谓的monkey patch就是运行时替换,本质上是对象的重新赋值
比如gevent库需要修改内置的socket:
from gevent import monkey;monkey.patch_socket()
运行时判断一个对象的类型的能力
python一切皆对象、用type、id、isinstance获取对象类型信息
比如[i for i in range(10) if i % 2 == 0]
一种快速生成list/dict/set的方式,用来替代map/filter等
import this
(1)print在Python3里是一个函数,在Python2里只是一个关键字
(2)Python3文件的默认编码是utf8,Python2文件的默认编码是ascii
(3)Python3的str是unicode字符串,而Python2的str是bytes
(4)Python3的range()返回一个可迭代对象,Python2的 range()返回一个列表,xrange()返回一个可迭代对象,
(5)Python3的除法返回float,Python2的除法返回int
(1)可变对象: list,dict,set
(2)不可变对象: bool,int,float,tuple,str…
用来处理可变参数,接收参数后,args会变成一个tuple,kwargs会变成一个dict
可变参数指的是,不知道参数数量
同时使用*args和kwargs时,*args参数必须要列在kwargs前,否则会报错。
def test(a,*args,**kwargs):
print(a)
print(args)
print(kwargs)
test(1,3,5,7,c='2',d=4)
输出为:
1
(3, 5, 7)
{‘c’: ‘2’, ‘d’: 4}
(1)Django的ORM框架操作数据库时,获取数据,更新数据等都有可能会异常
(2)socket通信时,recv()方法可能会因为对方突然中断连接导致异常
(1)GIL:Global Interpreter Lock,即全局解释器锁
(2)GIL是Cpython的特性,不是python的特性
(3)引入GIL是因为CPython的内存管理并不是线程安全的,为了保护多线程下对python对象的访问,每个线程在执行过程中都需要先获取GIL,保证同一时刻只有一个线程在执行代码
(4)GIL使得python的多线程不能充分发挥多核CPU的性能,对CPU密集型程序的影响较大
(5)解决办法3个:
- 换用其他解释器,比如Jpython
- 使用多进程Multiprocess
- 将需要使用多线程的部分利用C或Java等语言来写
生成器是一种可迭代对象,可以挂起并保持当前的状态
生成器遇到yield处会停止执行,调用next()或send()才会继续执行
定义一个生成器有两种方式,一种是生成器推导式,一种是在普通函数中添加yield语句并实例化
浅拷贝出来的是一个独立的对象,但它的子对象还是原对象中的子对象(拷贝地址)
深拷贝会递归地拷贝原对象中的每一个子对象,因此拷贝后的对象和原对象互不相关(拷贝值,重新分配地址)
可迭代对象类,必须自定义__iter__()
魔法方法,range,list类的实例化对象都是可迭代对象
迭代器类,必须自定义__iter__()
和__next__()
魔法方法,用iter()函数可以创建可迭代对象的迭代器
闭包就是一个嵌套函数,它的内部函数 使用了 外部函数的变量或参数,它的外部函数 返回了内部函数
可以保存外部函数内的变量,不会随着外部函数调用完而销毁
引用计数为主,标记清除 和 分代回收为辅
引用计数机制是这样的
当对象被创建,被引用,作为参数传递,存储到容器中,引用计数+1
当对象离开作用域,引用指向别的对象,del,从容器中移除,引用计数-1
当引用计数降为0,python就会自动回收该对象所在的内存空间,
但是引用计数无法解决循环引用的问题,所以引入了标记清除和分代回收机制
async: 声明一个函数为异步函数,函数内只要有await就要声明为async
await: 搭配asyncio.sleep()时会切换协程,当切换回来后再继续执行下面的语句
(1)内置数据结构: list,dict,tuple,set
(2)内置方法: sorted,max…
collections模块提供了一些好用的容器数据类型,其中常用的有: namedtuple,deque,Counter,OrderedDict,defaultdict
尤其是deque队列,用的特别多
dict底层是哈希表,哈希表类似于C语言的数组,可以实现按索引随机访问
但dict的key不一定是整数(ascii码),需要先通过哈希函数,再经过取余操作转换为索引
list和tuple底层都是顺序表结构
list底层是可变数组,数组里存放的是元素对象的指针
set的底层是哈希表,key就是元素,value都是空
class方法的第一个参数是cls,可以访问类属性,类方法
static方法和普通函数一样,只不过是放在类里,要通过类或实例来调用,但是它不能访问类和实例的属性和方法
装饰器是一个接收函数作为参数的闭包函数
它可以在不修改函数内部源代码的情况下,给函数添加额外的功能
import time
def calc_time(func):
def inner():
t1 = time.time()
func()
t2 = time.time()
print('cost time: {}s'.format(t2-t1))
return inner
元类是创建类的类,type还有继承自type的类都是元类
作用: 在类定义时(new, init)和 类实例化时(call) 可以添加自定义的功能
使用场景: ORM框架中创建一个类就代表数据库中的一个表,但是定义这个类时为了统一需要把里面的类属性全部改为小写,这个时候就要用元类重写new方法,把attrs字典里的key转为小写
class Foo():
__instance = None
def __new__(cls):
if cls.__instance is None:
cls.__instance = super().__new__(cls)
return cls.__instance
class MyType(type):
def __init__(self):
super().__init__()
self.__instance = None
def __call__(self,*args,**kwargs):
if not self.__instance:
self.__instance = super().__call__(*args,**kwargs)
return self.__instance
class Foo(metaclass=MyType):
...
def outter(cls):
dct = {}
def inner(*args,**kwargs):
if cls not in dct:
dct[cls] = cls(*args,**kwargs)
return dct[cls]
return inner
@outter
class Foo():
...
class CarFactory():
def produce(self,name):
if name == 'BYD':
return BYD()
elif name == 'BMW':
return BMW()
class BYD():
pass
class BMW():
pass
car = CarFactory().produce('BMW')
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。