python有哪些特点?
- python是解释性语言,因此python在运行之前不需要编译
- python是动态类型语言,因此在声明变量时,无需要指定变量类型
可变类型与不可变类型
可变数据类型:允许变量值发生变化,改变数据类型对应变量值,不会从新分配内存
不可变数据类型:不允许变量值发生变化,如果改变了该变量对应的值,那么会重新分配内存
列表,元组,字典,集合 区别
- 列表,集合,字典 为可变数据类型,就是改变其值后(比如append) 后,用ID查看其内存地址 不变
- 元组,字符串 为 不可变数据类型,改变后,ID值就 变了
- 元组是 只读 的,列表,字典,集合 可以 读写
什么是生成器?(重点)
- generator 生成器(接你为特),使用了yield(已有特)函数,被称为生成器
- 在python中一边循环,一边计算机制,叫做生成器
- 举个例子:生成0~9数的平方 使用 生成器表达式
a = (x * x for x in range(10))
print(a) # <generator object <genexpr> at 0x014C2488>
for i in a:
print(i)
# 0 1 4 9 16 25 36 49 64 81
- 优点:生成器的好处是延迟计算,一次返回一个结果。也就是说,它不会一次生成所有的结果,这对于大数据量处理,
-
什么是迭代器?
代器是一个可以记住遍历位置的对象。
- 迭代器的两个基本方法:
iter()
和next()
- 例子:创建迭代器 ```python list1 = [1, 2, 3, 4] list_it = iter(list1)
print(list_it) #
<a name="TQqjU"></a>
##
<a name="PxvG0"></a>
## 什么是lambda函数?
python中函数定义方式一种是def定义,另一种是lambda进行定义,不需要指定函数名
```python
# lambda函数语法形式
sum = lambda x, y: x + y
print(sum(1, 2)) # 3
什么是装饰器?(必问)
- 装饰器本质上是一个python函数,它可以让其他函数,在不需要做任何代码变动的前提下增加额外的功能,装饰器的返回值也是一个函数对象
- 例子:创建一个装饰器,记录方法执行时间
```python from time import time
def timeit(func): def wrapper(): start = time() func() end = time() print(‘used time:{}’.format(end - start))
return wrapper()
@timeit def foo(): print(‘这个是测试函数’)
<a name="tiKc3"></a>
## 什么是多进程(重点)
- **进程**:一个运行程序(代码)就是一个进程,**进程是操作系统分配的最小单位**
- **注意**:**一个程序运行后至少有一个进程,一个进程默认有一个线程**,进程里面可以创建多个线程,线程依附在进程里面,没有进程就没有线程
- 真正干活的是**线程**,进程只向操作系统索要资源
- **多进程,可以完成多个任务**
- 代码案例:创建2个子进程(唱歌,跳舞)
```python
import os
import time
import multiprocessing
# 跳舞任务
def dance(name):
for i in range(3):
print('{}正在跳舞...'.format(name))
time.sleep(0.5)
# 唱歌任务
def sign(name):
for i in range(3):
print('{}正在唱歌...'.format(name))
time.sleep(0.5)
if __name__ == '__main__':
# 创建子进程,target: 执行的目标任务, args以元组方式传参
# dance_process = multiprocessing.Process(target=dance, args=('job',))
# 以字典方式传参
dance_process = multiprocessing.Process(target=dance, kwargs={'name': 'job'})
dance_process.start()
sign_process = multiprocessing.Process(target=sign, args=('tom',))
sign_process.start()
#job正在跳舞...
#tom正在唱歌...
#tom正在唱歌...job正在跳舞...
#tom正在唱歌...
#job正在跳舞...
- 进程之间不共享全局变量
- 主进程会等待所有子进程执行完成以后再退出
- 解决方法:
- 主进程退出,子进程直接销毁
- 退出主进程之前,先让子进程销毁
什么是多线程?(重点)
在python中,实现多任务除了使用进程,还可以使用线程完成
概念:线程是CPU调度的基本单位
- 多线程之间可以共享全局变量
- 主线程会等待所有子线程执行结束在结束
多线程时使用:开启一个子线程执行dance任务(一共2个子线程,一个主线程,一个dance线程)
import time
import threading
def dance():
for i in range(3):
print('正在跳舞')
time.sleep(0.5)
if __name__ == '__main__':
dance_process = threading.Thread(target=dance)
dance_process.start()
print('主进程执行over')
# 正在跳舞
# 主进程执行over
# 正在跳舞
# 正在跳舞
- 资源竞争
- 互斥锁
- 死锁
多进程,多线程 优缺点
- 进程(跟计算密集型相关操作使用多进程)
- 优点:可以利用多核
- 缺点:资源开销大
- 线程(文件下载,写入,I/O操作)
- 优点:资源开销小
- 缺点:不能使用多核
多任务执行方式?
- 并发:在一段时间内 交替 执行任务
- 例如:对于单核CPU执行多任务,操作系统轮流让 各个软件执行0.01s(时间片),每个软件交替执行,这些软件看起来就像一起运行了。
并行:任务数小于核数
浅拷贝:copy,拷贝父对象,不会拷贝对象内部的子对象
- 深拷贝:deepcopy,完全拷贝了父对象及其子对象
浅拷贝案例:
深拷贝案例:
单下划线与双下划线区别(必问)
有时也会问私有属性与常规属性的区别
- python用下划线作为前缀和后缀指定特殊变量和定义方法 (4种形式)
- 单下划线(_)作为临时变量
- 名称前单下划线(_name)属性和方法是私有的
- 名称前双下划线(__name)
-
单下划线 _
- 接收一个函数返回的多个值时,如果一个值之后用不到,那么就直接用_代替就行了
-
名称前单下划线
_
(_name
)当在属性和方法前面加上单下划线
_
,用于指定属性和方法是私有的,表示该属性,方法,类只能在内部使用
像使用from ... import...
这些属性或方法,类不会被导入名称前的双下划线(
__name
)避免父类的方法被子类轻易覆盖 ```python class AMethod(object): def method(self): print(‘method in class AMethod’)
def method(self): print(‘method in class Amethod’)
class BMethod(AMethod): def method(self): print(‘method in class BMethod’)
a = AMethod() a.method() # method in class Amethod
b = BMethod() b.method() # method in class Amethod
<br />
<a name="SW0Fn"></a>
### 名称前后的双下划线(`__init__`)
**这类方法是**`**python**`**内部调用的方法,可以重写这些方法**
```python
class Number(object):
def __init__(self, number):
self.number = number
def __str__(self):
return str(self.number)
num = Number(100)
print(num) # 100