# 函数开头注释
def func(a):
"""
this is a test function
:param a: input data
:return: data user
"""
return 1, 2, 3
#函数类型与返回值
print(func( 1 )) # None
print(id(func)) # 38960288
print(type(func)) # <class 'function'>
d = func(1)
a, b, c = func(1)
print(d) # (1, 2, 3)
print(type(d)) # <class 'tuple'>
print(a, b, c) # 1 2 3
print(type(None)) # <class 'NoneType'>
print(type(False)) # <class 'bool'>
# 局部变量与全局变量
num = 200
print(id(num)) # 8790910181264
def test_func ():
# print(num) #此时存在bug,因为后面有局部变量num,如果没有局部变量num,则可以直接读全局的num
num = 100 # 此处修改的是局部变量的num并赋值为100,并不是修改全局变量,只是名字相同而已
print("test_func", num)
print(id(num)) # 8790910178064,与全局变量num不是同一个
def test_func_ex ():
global num
print(id(num)) # 8790910181264,与全局变量num不是同一个,此处输出200
num = 300 # 此处修改的是全局的变量num并赋值为300,修改全局变量
print("test_func_ex", num)
print(id(num)) # 31589392,此时修改的是全局的变量num
test_func()
print("num", num) # 输出200
test_func_ex()
print("num", num) # 输出300
print(id(num)) # 31589392,读取全局的变量num
def testfunc(aa, bb, cc):
print(aa,bb,cc)
testfunc(11,22,33)
testfunc(bb = 123, cc = 22, aa = 55) #关键字参数不需要按照顺序提供
# 命名参数必须放在最右边,同理默认参数也必须放在最右边
# testfunc(12, aa=100, cc=10) #执行时12赋给aa,100又给aa,10给cc,那么bb没有参数提示错误
print("\n\nNew test for args and kwargs:\n")
#不定长参数,*args:代表多个参数,组成元组传给函数;**kwargs,代表多个key:value类型参数,组成字典传递给函数
#*是修饰后面参数代表是多个普通参数,**代表是修饰后面是多个字典参数
def func_arg(*args):
print("func_arg", type(args)) #<class 'tuple'>
print("func_arg", args)
def func_kwarg(**kwargs):
print("func_kwarg", type(kwargs)) #<class 'dict'>
print("func_kwarg", kwargs)
def test_args(name, *args, **kwargs):
print(name)
print()
#args使用测试
print(type(args)) #输出<class 'tuple'>
print(args) #输出(123, 'abc', 'ddd')
# print(type(*args)) #写法错误,相当于print(type(123, 'abc', 'ddd')), 错误
print(*args) #输出123 abc ddd ,相当于解包print(123, 'abc', 'ddd'),展开成多个参数
# func_arg(args) #相当于传入一个参数:((123, 'abc', 'ddd'),),不推荐,除非特殊情况
func_arg(*args) #相当于传入三个参数:(123, 'abc', 'ddd'),正确用法
#type()函数传入一个参数时代表返回对象类型,传入3个参数(类型名,父类名,属性)时代表创建一个新类型
#kwargs使用测试
print(type(kwargs)) #输出<class 'dict'>
print(kwargs) #输出{'age': 45, 'score': 33, 'desc': 'heelo'}
# print(type(*kwargs)) #写法错误,相当于print(type('age', 'score', 'desc')), 错误
print(*kwargs) #输出age score desc ,相当于解包print('age', 'score', 'desc'),展开成多个key
# print(type(**kwargs)) #写法错误,相当于相当于print(type(age=45, score=33, desc='hello')),错误
# print(**kwargs) #解包后相当于执行print(age=45, score=33, desc='hello'),print函数不接受这种传参方式
# func_kwarg(kwargs)#相当于func_kwarg({'age': 45, 'score': 33, 'desc': 'heelo'}),而不是func_kwarg要求传入的键值对类型,错误
# func_kwarg(*kwargs)#相当于func_kwarg('age', 'score', 'desc'),而不是func_kwarg要求传入的键值对类型,错误
func_kwarg(**kwargs) #相当于func_kwarg(age=45, score=33, desc='hello')
#args:(123, 'abc', 'ddd')
#kwargs:{'age': 45, 'score': 33, 'desc': 'heelo'}
test_args("testargs", 123, 'abc', 'ddd', age=45, score=33, desc="heelo")
# test_args("testargs", 123, 'abc', 'ddd', age:45, score:33, desc:"heelo")
test_args(123) #args=(), kwargs={}
test_args('123', dd="123")#args=(), kwargs={'dd': '123'}
def test_funcarg1(a, b, c =100, d= 200, *args, **kwargs): #普通参数优先按位置传递给c,d,剩下的给args吸收
print(a,b,c,d,args,kwargs)
test_funcarg1(1, 2, 3, 4, 5, 6, name="123", heel='233') #参数赋值顺序为:1 2 3 4 (5, 6) {'name': '123', 'heel': '233'}
def test_funcarg2(a, b, *args, c =100, d= 200, **kwargs): #普通参数尽可能的被args吸收,不会传给c,d
print(a,b,c,d,args,kwargs)
test_funcarg2(1, 2, 3, 4, 5, 6, name="123", heel='233') #参数赋值顺序为:1 2 100 200 (3, 4, 5, 6) {'name': '123', 'heel': '233'}
data = {'name':'hello', 'age':23, 'score':22}
data2 = {'name1':'hello', 'age1':23, 'score1':22}
def funkwarg(name, age, score):
print(name, age, score)
# funkwarg(data) #等价于funkwarg({'name':'hello', 'age':23, 'score':22}),传递一个参数语法错误缺少参数
funkwarg(*data) #等价于funkwarg('name', 'age', 'score')
funkwarg(**data) #等价于funkwarg(name='hello', age=23, score=22)
# funkwarg(**data2) #等价于funkwarg(name1='hello', age1=23, score1=22) ,键值对错误,没有相应关键字参数
def test_a(*args, **kwargs):
print('test_a', args)
print('test_a', kwargs)
def test_b(*args, **kwargs):
print('test_b', args) #(11, 22, 33)
print('test_b', kwargs) #{'name': 'heelo', 'age': 123}
# test_a((11, 22, 33), {'name': 'heelo', 'age': 123})等价于输入一个参数
#args=((11, 22, 33), {'name': 'heelo', 'age': 123}), kwargs={}
test_a(args, kwargs)
# test_a(11, 22, 33, 'name', 'age')等价于输入5个参数
#*args=(11, 22, 33), *kwargs=('name', 'age'),最后都被吸收到test_a的第一个参数
test_a(*args, *kwargs)
# test_a(11, 22, 33, name='heelo', age=123)等价于输入五个参数
#**args=11, 22, 33, *kwargs=(name='heelo', age=123),最后都被吸收到test_a的第一个参数
test_a(*args, **kwargs)
test_b(11, 22, 33, name='heelo', age=123)
#python中一切变量名都是一个地址,包括函数名,类名,可以随便指向
def func():
print(1)
return 1
p =func
# <class 'function'> <class 'function'> <function func at 0x000000000254B430> <function func at 0x000000000254B430>
print(type(p),type(func),p, func)
print(id(p), id(func)) # 39105584 39105584
func = [123,12]
print(type(func),func,id(func)) # <class 'list'> [123, 12] 39109696
#匿名函数,也就是lambda函数
# lambda 形参1,形参2.....: 表达式
#一般定义一个变量指向匿名表达式,然后通过该变量调用,且lambda函数只能有一行
#匿名函数的表达式部分会自动作为函数的返回值,如下例中的x+y会自动作为返回值
test = lambda x,y: x+y
result = test(2,3)
print(result)
#lambda函数当参数
def func(a, b, test):
return test(a, b)
func(100, 200, lambda a,b: a+b)
#无参数lambda函数
test = lambda : print("heelo")
test() #输出heelo
#列表中元素为字典按age排序
data = [{'name' :"hel", 'age':12},
{'name': "hedl", 'age': 32},
{'name': "hesl", 'age': 22},]
(reverse=True, key=lambda temp_dict:temp_dict['age']) #对列表进行排序,使用lambda方式
print(data)
def sort_func(temp_dict):
return temp_dict['age']
(reverse=False, key=sort_func) #对列表进行排序,使用函数方式
print(data)
#递归函数
def func(a):
if a ==1 :
return 1
else:
return a* func(a-1)
print(func(998)) #最多递归998次