Python基础0227
函数
函数是组织好的、可重复使用的、实现的单一功能的代码段。函数一般都有输入(参数)和输出(返回值)。Python中函数是一等对象(first class),意味着它们可以被赋值,从其他函数返回值,并且传递函数对象。
函数定义
def func(args):
pass
函数调用
func(args)
函数参数
def add(x,y):
return x + y
位置参数和关键字参数
位置参数和关键字参数在调用的时候决定
def add(x,y):
print('x={0}.format(x)')
print('y={0}.format(y)')
return x + y
add(1,2)
add(y=1,x=2)
add(1,x=2)
- 位置参数 通过参数传递的位置来决定
- 关键字参数 通过参数名称来决定
混合使用关键字参数必须在位置参数之后
默认参数
def inc(x,i=1):
return x + i
inc(5)
inc(5,i=3)
- 默认参数在调用的时候可以省略
- 默认参数必须在非默认参数之后
可变参数\可变位置参数
def sum(*args):
ret = 0
for x in args:
ret += x
return ret
- args 将多个参数组装成一个元组
- args 不限制参数的位置
可变关键字参数
def print_info(**kvargs):
for k,v in kvargs.items():
print('{0}=>{1}'.format(k,v))
print_info(a=1,b=2,c=3)
- kvargs 将多个关键字参数组装成字典
- 可变参数函数在定义的时候,就决定了参数是位置参数还是关键字参数
def print_info(*args,**kvargs):
for i in args:
print(i)
for k,v in kvargs.items():
print('{0}==>{1}'.format(k,v))
print_info(1,2,3,a=3,b=4)
- 定义参数一般顺序:非默认 非可变参数 可变位置参数 可变关键字参数
- 默认参数
不要和可变参数放到一起
def print_info(x,y,*args,**kvargs):
print('x={0}'.format(x))
print('y={0}'.format(y))
for i in args:
print(i)
for k,v in kvargs.items():
print('{0}==>{1}'.format(k,v))
print_info(1,2,3,4,5,a=3,b=4)
参数解包
def add(x,y):
print('x is {0}'.format(x))
print('y is {0}'.format(y))
return x + y
lst = [1,2]
add(*lst)
x is 1
y is 2
3
d={"x":1,"y":2}
add(**d)
x is 1
y is 2
3
add(*[1,2])
x is 1
y is 2
3
add(**{"x":1,"y":2})
x is 1
y is 2
3
- 解包参数需要和函数定义的参数变量名和数量一一对应
- *args 将收集的所有位置参数,放到一个
元组中,最后将这个元组赋值给args - **kvargs将收集的所有关键字参数,放到一个
字典中,最后将这个字典赋值给kvargs - 收集参数,形参中利用
*和**实现 - 参数解包,实参中利用
*和**实现
def mymap(func,*seqs): #封装成元组 * 收集参数
res=[]
print(seqs) #封装后的元组
for args in zip(*seqs): #zip函数接受 seqs元组解包后的列表(可迭代对象),每次返回一个元组对象。 * 解包参数
res.append(func(*args)) # * 解包参数 args是zip返回的元组对象
return res
print(mymap(abs,[-2,-1,0,1,2]))
([-2, -1, 0, 1, 2],) #列表整体会被当成一个参数
[2, 1, 0, 1, 2]
默认参数的坑
def fn(lst=[]):
print(id(lst))
lst.append(1)
print(lst)
fn()
4442085896
[1]
fn()
4442085896
[1, 1]
默认参数不是赋值,而是指向一个函数内部新的对象,对这个对象的任何修改都会改变引用它的初始值。因此默认参数通常指向不可变对象。
def fn(lst='None'):
if lst is None:
lst=[]
lst.append(1)
print(id(lst))
print(lst)
未定义lst时,每次执行函数都指向一个新的空列表对象(id不一样)。
函数返回值
- 使用return关键字返回
- 可以返回任何对象
- 可以通过解包变相返回多值
- 默认返回
None
def fn():
pass
type(fn())
NoneType
def fn():
return 1,2,3,4
fn()
(1, 2, 3, 4)
type(fn())
tuple
def fn()
for i in range(5):
print(i)
if i > 2:
return
fn()
0
1
2
3
type(fn())
0
1
2
3
NoneType
递归函数
python中尽量避免使用递归,最大递归深度小于1000,实际测试大于998之后就会报错。
def func(x):
if x > 1:
return func(x-1)*x
else:
return 1
等价于
a=1
for i in range(1):
a=a*i
print(a)
变量作用域
作用域是指变量在程序中的可见范围,变量的作用域通常就是定义他们的代码块。
- 局部变量:在函数体内定义的变量,其作用域为函数体内部,和函数体外的参数没有关系。
- 全局变量:定义在函数体外的变量,对全局可见的变量,函数体内也可继承这个变量。
不建议使用 global语句可以在函数体内定义全局变量,之后对变量的操作都是对全局变量的操作。
x = 50
def func():
global x
x = 2
print(x)
func()
print(x)
2
2
globals() 可用全局变量
locals() 可用本地变量
函数调用过程
栈 和 堆 可以参考什么是堆和栈,它们在哪儿?
生成器
def fun():
i = 1
print("I am fun")
while i < 6:
yield i
print("I am yield")
i = i + 1
def main():
print("I am main")
for i in fun():
print("i")
print("I am for_loc")
main()
print("===")
def main1():
print("I am main1")
if 1 in fun(): #条件加次数限制的循环,多次执行生成器直至命中或次数耗净。
print("Y")
print("I am for_loc")
main1()
I am main
I am fun #开始调用函数fun
i #yield返回i给主函数main的for循环,并暂存fun函数
I am for_loc #main函数循环体执行完成,并再次指向函数fun
I am yield #从上次暂存点继续执行fun函数
i #while循环满足再次遇到yield,暂存fun函数,返回i给main函数
I am for_loc
I am yield
i
I am for_loc
I am yield
i
I am for_loc
I am yield
i
I am for_loc #main函数循环体执行完成,并再次指向函数fun
I am yield #从上次暂存点继续执行fun函数
=== #while条件不满足,fun结束,返回None给for循环,main函数结束
I am main1
I am fun
Y
I am for_loc
能让生成器遍历其中元素的,除了for循环之外,还可以使用if in成员判断。
惰性求值
def fun(x):
a = 1
for i in range(1,x+1):
a = a * i
yield a
fun(5)
<generator object fun at 0x7ff016f1f3a8>
next(fun(5))
1
next(fun(5))
1 # 每次调用迭代器本身,都从新开始,没有状态保持。
it = fun(5)
next(it)
1
next(it)
2 # 赋值引用之后,迭代器对象确定之后,每次执行都保存上一次的值。

浙公网安备 33010602011771号