文章目录
- 函数和函数式编程
- 函数
- 函数式编程
函数和函数式编程
函数
声明函数:
def hello():
print("hello function!")
调用函数:
# 使用()调用
hello()#output:hello function!
# 没有(),则不进行调用,一切皆是对象,函数也是对象
print(hello)#output:<function hello at 0x000001EE36F1B3A0>
hello#output:<function __main__.hello()>
print(hello.__class__)#output:<class 'function'>
print(type(hello))#output:<class 'function'>
print(type(hello()))
#output:
#hello function!
#<class 'NoneType'>
xxx = hello
print(xxx.__name__)#output:hello
函数—可变不可变对象
可更改(mutable)与不可更改(immutable)对象
在python中, strings, tuples,和 numbers是不可更改的对象,而list,dict等则是可以修改的对象。
- **不可变类型:**变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。
- **可变类型:**变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
python 函数的参数传递:
- **不可变类型:**类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a的值,只是修改另一个复制的对象,不会影响 a 本身。
- **可变类型:**类似 c++的引用传递,如列表,字典。如fun (la),则是将 la 真正的传过去,修改后fun外部的la也会受影响python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。
可变类型:
def changeme(mytest_List):
mytest_List.append([1, 2, 3, 4])
print("函数内取值:", mytest_List)
return
#调用changeme函数
mytest_List = [100, 200, 300]
print(mytest_List)
changeme(mytest_List)
print("函数外取值:", mytest_List)
#output:
#[100, 200, 300]
#函数内取值: [100, 200, 300, [1, 2, 3, 4]]
#函数外取值: [100, 200, 300, [1, 2, 3, 4]]
不可变类型:
def change_int(a):
a = 10
b = 3
change_int(b)
print(b)
#output:3
函数—参数
-
必备参数
-
定义
def func(p): print(f"p is {p}")
-
调用
func(1)#output:p is 1 func(p=1)#output:p is 1
-
-
默认参数
def func(a, b=1, c=2): print(f"a={a}, b={b}, c={c}") func(1, 1, 1) func(1, c=1) func(1) # output: # a=1, b=1, c=1 # a=1, b=1, c=1 # a=1, b=1, c=2
-
可变参数
def func(a, *args, **kwargs): print(f"a={a}, args={args}, kwargs={kwargs}") func(1, 1, 1) func(1, c=1) func(1) func(1, 2, 3, x=8) # output: # a=1, args=(1, 1), kwargs={} # a=1, args=(), kwargs={'c': 1} # a=1, args=(), kwargs={} # a=1, args=(2, 3), kwargs={'x': 8}
-
可变参数调用
# *变量名 元组传入参数 args = (0, 10, 2) print(list(range(*args))) # output: # [0, 2, 4, 6, 8] # **变量名 字典传入参数 from datetime import datetime print(datetime(year=1999, month=7, day=1)) # output: # 1999-07-01 00:00:00 kwargs = {"year":1999, "month":7, "day":1} print(datetime(**kwargs)) # output: # 1999-07-01 00:00:00
函数—函数返回值
在函数体内使用return语句可以从函数中返回一个值并跳出函数的功能。
- 多条return语句:
return语句可以放在函数中任何位置,当执行到第一个return语句时程序返回到调用程序。
- 返回多个值:
如果需要返回多个值,则可以返回一个元组。
函数—Built-in 函数
内置函数:
函数—作用域
-
LEGB解析顺序:Local, Enclosing, Global, Built-in
-
global关键字
total = 100 # 这是一个全局变量 def sum(arg1, arg2): total = arg1 + arg2 # 这里是局部变量 print("函数内是局部变量:", total) return total sum(10, 20) print("函数外是全局变量:", total) # output: # 函数内是局部变量: 30 # 函数外是全局变量: 100
注意:
- 全局变量大写首字母,局部变量全小写
- 不要使用Built-in和关键字作变量/函数名
- python中print函数需要返回值,如果你在print函数中没有返回值,那么print将会return None
全局语句global
在函数体中可以引用全局变量,但如果函数内部的变量名时第一次出现在赋值语句之前(变量赋值),则解释为定义局部变量。
如果要为定义在函数外的全局变量赋值,可以使用global语句,表明变量是在外面定义的全局变量。global语句可以指定多个全局变量。
#全局变量
Pi = 3.1415
E =2.71828
def my_func():
global Pi #全局变量,于前面的全局变量Pi指向相同对象
Pi = 3.1 #改变全局变量的值
print("global Pi= ", Pi)#输出全局变量值
E = 2.7 #局部变量,与前面的全局变量E指向不同的对象
print("local E = ", E)#输出局部变量值
print("module Pi= ", Pi)
print("module E= ", E)
my_func()
print("module Pi= ", Pi)# 输出全局变量的值,该值在函数中已被更改
print("module E= ", E)
# output:
# module Pi= 3.1415
# module E= 2.71828
# global Pi= 3.1
# local E = 2.7
# module Pi= 3.1
# module E= 2.71828
非局部语句nonlocal
在函数体中可以定义嵌套函数,在嵌套函数中如果要为定义在上级函数体的局部变量赋值,可以使用nonlocal语句,表明变量不是所在块的局部变量,而是在上级函数体中定义的局部变量。
# module E= 2.71828
#%%
def outer_func():
tax_rate = 0.17 #上级函数体中的局部变量
print("outer func tax rate= ", tax_rate)#输出上级函数体中局部变量的值
def inner_func():
nonlocal tax_rate # 不是所在块的局部变量,而是在上级函数体中定义的局部变量
tax_rate = 0.05 # 上级函数体中的局部变量重新赋值
print("inner func tax rate= ", tax_rate) # 输出上级函数体中局部变量的值
inner_func()
print("outer func tax rate= ", tax_rate) # 输出上级函数体中局部变量的值(已更改)
outer_func()
# output:
# outer func tax rate= 0.17
# inner func tax rate= 0.05
# outer func tax rate= 0.05
函数式编程
函数式编程
input -> f1 -> f2 -> f3 ->f4 -> f5 -> output
函数式编程vs面向对象编程
- First-class function,简化很多设计模式
- 更简单的函数-更好编写和维护
- 更容易做单元测试
- 更容易跨线程,跨进程,甚至跨机器执行任务
匿名函数
lambda
优势:结构体简单,函数体简短场景适用,即用即弃
a = [0, 1, 2, 3, 4, 5]
result = filter(lambda x: x % 2 == 0, a)
print(list(result))
# output:[0, 2, 4]
- filter()
filter(func, lst)函数⽤于过滤序列, 过滤掉不符合条件的元素, 返回⼀个 fifilter 对象,。如果要转换为列表
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def func(x):
return x % 2 == 0
result = filter(func, list1)
print(result)
print(list(result))