1.函数

Python的函数创建不太一样(与c++相比),调用倒是一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def MyFunc() :
print("nihao!")
print("over!")
# 因为Python没有数据类型,所以也就不需要设置返回值

MyFunc() # 直接调用

# 带参数的时候也没数据类型!
def MyFunc2(name1,name2) :
print("hello" + name1 + name2)

# 同样可以带返回值(可以返回多种类型,包括列表,多个默认为元组)
def MyFunc3(name) :
print("hello" + name)
return [123,"123",1.23]

# 可以有默认参数
def MyFunc4(name = "hello")

# 可以放元组(收集参数*)
def MyFunc5(*num,name) # 当收集参数后面还有参数,要用关键参数来指定
MyFunc5(1, 2, 3, 4, name = "wtc")

print函数的原形

1
2
print(*object, sep=' ', end='\n', file=sys.stdout, flush=False)
# sep是分隔符,end是结束,file指定输出位置,flush是否强制刷新缓存
1
2
3
4
5
6
# *在形参中是打包,在实参中是解包
num = [1, 2, 3]
>>> print(num)
[1, 2, 3]
>>> print(*num)
1 2 3

全局函数 和 局部函数

Python只要有定义不管是前面还是后面都可以用,不是在函数里面的就是全局变量,在函数里面的是局部变量,但是有一点需要注意:

在函数里试图修改全局变量会自动生成一个与全局变量相同的局部变量来代替(防止出现问题),也就是在函数里面不会修改全局变量(和C++不同)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
x = 2
def Func()
x = 1
print(x)
Func()
print(x)
# 这样的话先输出1,再输出2,调用函数的时候不会修改全局变量

x = 2
def Func()
global x
x = 1
print(x)
Func()
print(x)
# 这样就会强制修改了x的数值

可以用global关键字来强制修改全局变量

2.闭包

闭包的概念是由内部函数而来,所以不能在外部函数以外的地方对内部函数进行调用

1
2
3
4
5
6
7
8
def FunX() :
x = 5
def Funy :
x = x + 1
return x
return Funy()

# 在Funy中把外界的x给屏蔽了所以在x = x + 1 中右边的x是找不到的,因此会报错

容器类型不是放在栈中,所以不会被“屏蔽”掉

1
2
3
4
5
6
7
8
9
10
def FunX() :
x = [5]
def Funy :
x[0] = x[0] + 1
return x[0]
return Funy()

>>> tmp = FunX()
>>> tmp()
6

或者用nonlocal关键词(类似global)

1
2
3
4
5
6
7
8
9
10
11
def FunX() :
x = 5
def Funy :
nonlocal x
x = x + 1
return x
return Funy()

>>> tmp = FunX()
>>> tmp()
6

3.装饰器

将一组程序放入一个闭包,保证一个函数只做一件事。

1
2
3
4
5
6
7
8
9
10
11
def log(func) :
def wrapper() : # 闭包
print("开始调用eat()函数……")
func()
print("结束调用eat()函数……")
return wrapper # 不用加括号

def eat() :
print("开始吃了")
eat = log(eat) # 把eat函数作为参数传递给log(),wrapper是log的闭包所以可以直接调用func函数(与eat函数效果相同)
eat()

语法糖

这是为了让程序更简洁

1
2
3
4
5
6
7
8
9
10
11
12
def log(func) :
def wrapper() : # 闭包
print("开始调用eat()函数……")
func()
print("结束调用eat()函数……")
return wrapper # 不用加括号

@log # 语法糖
def eat() :
print("开始吃了")
eat()
# 此时调用eat相当于调用 log(eat())

如果eat带参数可以加在log里面的wrapper上 (要随时确保与eat的相同)

1
2
3
4
5
6
7
8
9
10
11
12
def log(func) :
def wrapper(name) : # 闭包
print("开始调用eat()函数……")
func(name)
print("结束调用eat()函数……")
return wrapper # 不用加括号

@log # 语法糖
def eat(name) :
print("%s 开始吃了" % name)
eat()
# 此时调用eat相当于调用 log(eat(name))

4.函数式编程

lambda创建匿名函数

1
2
3
4
5
6
7
8
9
def ds(x) :
return 2 * x + 1
>>> ds(5)
11

g = lambda x : 2 * x + 1 # 绑定临时名字
>>> g(5)
11

就看书来言感觉对于目前来说没有啥实际意义,所以不多研究。

filter过滤器筛选

1
2
3
4
5
6
7
8
def odd(x) :
return x % 2
temp = filter(odd , range(10)) # filter(规则,列表) 把列表元素逐个按照规则尝试
list(temp)
[1, 3, 5, 7, 9]

#这个倒是可以配合上面的函数
list(filter(lambda x:x%2 , range(10)))

map映射

其实跟上面差不多,上面是看规则是 True 或者 False,而map是输出得到的结果是什么

1
2
3
4
5
6
7
# 单个映射
list(map(lambda x:x*2 , range(10)))
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

# 多个映射
list(map(lambda x,y:x+y , [1,3,5],[10,30,50,66,88])
[11,33,55]

5.递归

设置递归深度

Python的保护机制会默认有限制,可以自己设定,但是不能太大(如 100000000)还是可能会崩溃

1
2
import sys
sys.setrecursionlimit(10000) # 将递归深度限制为一万层