1. 关于 Python 的变量的默认值
运行以下代码,会有惊喜!
def func(x,l=[]):
for i in range(x):
l.append(i*i)
print(l)
func(2)
func(3,[3,2,1])
func(3)
这段代码会输出:
[0, 1]
[3, 2, 1, 0, 1, 4]
[0, 1, 0, 1, 4]
惊不惊喜,意不意外。 这是因为
- Python 中,参数的默认值,也相当于变量一样,指向内存中的唯一的地址,除非你传进来了一个参数,改变这个参数的指向。
- 如果你在程序的运行过程中(使用了默认变量),修改了这个变量的值(可变),那么恭喜你,你的默认参数已经变了!
2. 一行代码实现 1--100 的和
简单点我们就用:
sum(range(1,101))
这里主要要记住的就是 range 是返回一个==迭代器==,==左闭右开==。
python2.x 的 range 是返回的数组,
python3.x 的 range 是返回迭代器。
尝试运行:
print(sum(range(1, 101)))
# 只是摆在这里告诉你这是最高效(NB)的写法。没任何毛病。不要死脑筋
print("5050")
print(range(1, 10))
print(list(range(1, 10)))
out:
5050 5050 range(1, 10) [1, 2, 3, 4, 5, 6, 7, 8, 9]
那为什么会这样呢?其实在 Python3 中 range()函数返回的对象很像一个列表,但是它确实不是一个列表,它只是在迭代的情况下返回指定索引的值,它并不会在内存中产生一个列表对象,官方解释说这样做是为了节约内存空间。通常我们称这种对象是可迭代的,或者是可迭代对象。
这里就要引入另外一个叫迭代器的概念,迭代器可以从一个可迭代对象中连续获取指定索引的值,直到索引结束。比如 list()函数,所以在上面的例子中,我们可以用 list()这个迭代器将 range()函数返回的对象变成一个列表。
由此可以看出:range()函数返回的是一个可迭代对象(类型是对象),而不是列表类型;list() 函数是对象迭代器,把对象转为一个列表,返回的变量类型为列表。
3. 如何在一个函数内部修改全局变量
在函数内部使用 global 声明,修改全局变量,作用域的知识点。
a = 5
b = 4
def fn():
# 在需要修改全局变量的时候,在前面加上global修饰
global a
print("Global a: ", a)
print("Global b: ", b)
a = 4
# 此路不通,IDE都会告诉你不能执行
# 全局变量在不声明global的时候不能修改,但是能读取
# b = 5
print("Global a: ", a)
print("Global a: ", a)
fn()
print("Global a: ", a)
out:
Global a: 5 Global a: 5 Global b: 4 Global a: 4 Global a: 4
4. Python 的几个标准库
| 库名 | 作用 |
|---|---|
| os | 提供了不少与操作系统相关联的函数 |
| sys | 通常用于命令行参数 |
| re | 正则匹配 |
| math | 数学运算 |
| datetime | 处理日期时间 |
5. 字典如何删除键和合并两个字典
字典基操
dic = {"name": "zs", "age": 18}
print(dic)
del dic["name"]
print(dic)
dic2 = {"name": "ls"}
dic.update(dic2)
print(dic)
- 补充一下知识点,删除对象属性的时候调用
__delattr__()或者super.__delattr__()或者直接使用del self.__dict__[key]
6. 关于 GIL 锁
-
一号解释:
GIL 是 python 的全局解释器锁,同一进程中假如有多个线程运行,一个线程在运行 python 程序的时候会霸占 python 解释器(加了一把锁即 GIL),使该进程内的其他线程无法运行,等该线程运行完后其他线程才能运行。如果线程运行过程中遇到耗时操作,则解释器锁解开,使其他线程运行。所以在多线程中,线程的运行仍是有先后顺序的,并不是同时进行。
多进程中因为每个进程都能被系统分配资源,相当于每个进程有了一个 python 解释器,所以多进程可以实现多个进程的同时运行,缺点是进程系统资源开销大。
-
二号知识点:
多线程和多进程是不一样的。
多进程是真正的并行,而多线程是伪并行,实际上他只是交替执行。
是什么导致多线程,只能交替执行呢?是一个叫 GIL(Global Interpreter Lock ,全局解释器锁)的东西。
GIL 的概念:
任何 Python 线程执行前,必须先获得 GIL 锁,然后,每执行 100 条字节码,解释器就自动释放 GIL 锁,让别的线程有机会执行。这个 GIL 全局锁实际上把所有线程的执行代码都给上了锁, 所以,多线程在 Python 中只能交替执行,即使 100 个线程跑在 100 核 CPU 上,也只能用到 1 个 核
这个是 Python 的解释器 CPython 引入的概念。还有其他解释器。但是默认的认为 Python == CPython
默许了 Python 有 GIL 锁这个东西。
避免 GIL 锁的方法:
- 使用多进程代替
- 不使用 CPython
7. Python 实现列表去重
Python 内置的集合是没有重复值的,数据到集合(set)里跑一圈就行了。
记住,是跑一圈!!!最后还要转成集合(list)
lst = [11, 12, 13, 12, 15, 11, 13]
tmp = set(lst)
print(type(tmp))
lst = [i for i in tmp]
print(lst)
out:
<class 'set'> [11, 12, 13, 15]
8.阐述*args和**kwargs
*args和*kwargs主要用于函数定义。
- 你可以将不定数量的参数传递给一个函数。这里的不定的意思是:预先并不知道函数使用者会传递多少个参数给你,所以在这个场景下使用这两个关键字。
*args是用来发送一个非键值对的可变数量的参数==元组(不可变)==给一个函数 **kwargs允许你将不定长度的键值对,作为参数传递给一个函数。如果你想要在一个函数里处理带名字的参数你应该使用**kwargs。这里传输的是字典。
这里有类似前端的解包的概念。
补充:
- 对于参数的传递,不指定 key 值的时候,按顺序传递。
- args 和 kwargs 只是大家约定俗成写这个,也就不要乱起名字了。
def func(a, *args, **kwargs):
print(type(args))
print(args)
print(type(kwargs))
print(kwargs)
func(10, 20, 30, b=40, d=50)
out:
<class 'tuple'> (20, 30) <class 'dict'> {'b': 40, 'd': 50}
9.解释一波装饰器
对于一些可以将函数传递的语言,都可以用装饰器。
装饰器(decorator)接受一个 callable 对象 (可以是函数或者实现了 call 方法的类)作为参数,并返回一个 callable 对象。
灵魂就是将函数 A 传递到另外一个函数 B 中,然后使用 B 调用 A,这样可以给 A 增加额外的功能。
简单的装饰器:
def outer(my_func):
print("step 1 : outer")
def inner(num):
print("step 2 : 进入内部函数")
return my_func(num)
return inner
@outer
def my_func(num):
print("step 3 : my_func,传入的参数:", num)
num += 1
return "加1之后:" + str(num)
print(my_func(num=100))
out:
step 1 : outer step 2 : 进入内部函数 step 3 : my_func,传入的参数: 100 加 1 之后:101
高级装饰器:
def outer(str):
print("outer")
def outer1(func):
print("outer1")
def inner():
print(str)
print("inner")
return func()
return inner
return outer1
@outer("哈哈哈")
def func():
print("func")
func()
out:
outer outer1 # 到此处都是装饰的时候生成的,下面才是调用的时候生成的 哈哈哈 inner func
一个用来实现函数运行时间计算的装饰器:
def print_func_time(function):
@wraps(function)
def func_time(*args, **kwargs):
t0 = time.perf_counter()
result = function(*args, **kwargs)
t1 = time.perf_counter()
print("Total running time: %s s" % (str(t1 - t0)))
return result
return func_time
10. Python 常见内建数据类型
| 表示 | 含义 |
|---|---|
| int | 整形 |
| bool | 布尔型 |
| str | 字符串 |
| list | 列表 |
| tuple | 元组 |
| dict | 字典 |