Python 的一些特性和语法
总结一些自己跳过的坑
Python3.5
对象皆引用
- 不同于 C++,Python 只有传引用,不存在传值,在 Python 中,一切皆对象,变量只是对对象的引用
- Python 中不需要声明变量类型也是基于此 a 和 b 都只是引用一个整型值 3,修改 b,a 的引用值也会变化
1
2a=3
b=a - 如果要拷贝,可以用 b=a [:]
string 是常量
- 字符串不能更改,只能在原先字符串上更改后赋给一个新字符串,原字符串依然不变
lambda 匿名函数
- 简化函数书写,lambda 参量:计算式
- 主要用于排序或者 reduce
- lambda 的参数是自由变量,是运行时绑定值,而不是定义时绑定值,如果要实现定义时绑定值,则定义之后在 lambda 中设置默认参数 如果不设置默认参数,上面的运行结果就是 30
1
2
3
4
5
6x=10
a=lambda y,x=x:x+y
x=20
print(a(10))
20
迭代器与生成器
- 通过重写对象的__iter__方法实现自定义迭代器,生成器 yield 实现迭代器的 next 方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22class Countdown:
def __init__(self, start):
self.start = start
def __iter__(self):
n = self.start
while n > 0:
yield n
n -= 1
def __reversed__(self):
n = 1
while n <= self.start:
n += 1
for rr in (Countdown(3)):
print(rr)
3
2
1
enumerate
- 同时输出迭代对象和索引,参数为索引开始号
1
2for idx,val in enumerate(my_list,1):
print(idx,val)
函数
- 接收任意个参数 * 接任意数量的位置参数,也可以用 ** 接一个字典,代表任意数量的关键字参数,也可以混用 * 和 **
1
2def avg(first,*rest):
return (first+sum(rest))/(1+len(rest))
顺序 (任意个位置参数,*,最后一个位置参数,其他参数,**) - 函数返回多个值
直接 return a,b,c,实际上返回的是一个元祖
装饰器
- 一个装饰器就是一个函数,它接收一个函数作为参数并返回一个新的函数 在上例中,timethis 是包装器,其定义中 func 是被包装的函数,args 和 kwargs 是任意数量的位置参数和关键字参数,来保证被包装的函数能正确接收参数执行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24import time
from functools import wraps
def timethis(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(func.__name__, end - start)
return result
return wrapper
def loop(n):
while n > 0:
n -= 1
loop(100000)
0.03971695899963379 loop
可以看到包装器中实现了一个 wrapper 装饰器函数,它运行了作为参数的 func 函数并计算打印了运行时间,一般装饰器函数返回原函数的执行结果 - 可以看到 timethis 中的 @wraps 本身也是一个装饰器,它用来注解底层包装函数,这样能够保留原函数的元信息,还能通过装饰器返回函数的__wrapped__属性直接访问到被装饰的函数,用来解除装饰
逗号的特殊作用
- 输出时换行变空格
- 转换类型为元组
filter
- 接收一个函数和序列,将函数作用于序列中每一个元素上,根据返回值决定是否删除该元素
1
2
3
4def is_odd(n):
return n % 2 == 1
filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])
any
- 原型:
1
2
3
4
5def any(iterable):
for element in iterable:
if element:
return False
return True
yield
- 一个带有 yield 的函数就是一个 generator,它和普通函数不同,生成一个 generator 看起来像函数调用,但不会执行任何函数代码,直到对其调用 next ()(在 for 循环中会自动调用 next ())才开始执行。虽然执行流程仍按函数的流程执行,但每执行到一个 yield 语句就会中断,并返回一个迭代值,下次执行时从 yield 的下一个语句继续执行。看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。
1
2
3
4
5
6
7
8def g(n):
for i in range(n):
yield i **2
...
for i in g(5):
print i,":",
...
0 : 1 : 4 : 9 : 16 :
v1.4.14