函数 - 参数/返回值/变量/嵌套函数/作用域/匿名函数/高阶函数/递归/内置方法
1.函数
函数:函数是指将一组语句的集合通过一个名字(函数名)封装起来。要想执行这个函数,只需调用其函数名即可。
特性:
   1.减少重复代码
   2.程序变得可扩展
   3.程序变得易维护 
def sayhi(): #函数名 - 小写
    print("hello")
sayhi() #调用函数   
-----------------------------
2.参数的作用:可以让程序更灵活,不只能做死的动作,还可以根据调用时传参的不同来决定函数内部的执行流程
形参:
实参:
def calc(x,y):  #x,y是形参,值过来后才调用内存 调用完成释放内存 
    res = x**y
    print(res)
calc(3,3)  #3,3 是实参 常量 变量 函数 什么类型都行  
默认参数:---->必须放到位置参数后面
位置参数
def stu_refigter(name,age,course,country='CN') ---> 前面的叫位置参数
stu_register('alice',12,'python')  
stu_register('rain',15,'python','english') 
关键参数:--->关键参数必须放到位置参数后面  
stu_register('alex',12,country='US',course='python')
----------------------------
3.非固定参数:--> 元组形式的 
def send_alert(msg,*users):  #users 元组   *args (一般这样写专业)
    for u in users:
        print('报警发送给',u)
如果参数中出现 *user,传递的参数就可以不再是固定个数,传过来的所有参数打包元组
方式一:send_alert('这是msg','alice','xxx','xxx','xxx')
方式二:send_alert('这是msg',['alice','xxx','xxx','xxx'])  把整个列表打包成元组 有问题
        send_alert('这是msg',*['alice','xxx','xxx','xxx']) 可以
非固定参数:-->关键字参数 字典形式的 
def func(name,*args,**kwargs):
    print(name,args,kwargs)
func('alex',22,'tesla','500w')
alex (22, 'tesla', '500w') {}
def func(name,*args,**kwargs):
    print(name,args,kwargs)
func('alex',22,'tesla','500w',addr='山东',num=123)
alex (22, 'tesla', '500w') {'addr': '山东', 'num': 123}
d={'degree':'primary school'}  
func('alice',**d)  
alice () {'degree': 'primary school'}   
-----------------------------
4.函数的返回值:
函数的返回值确定执行的结果 return 
遇到return 停止返回 
未指定返回None
return name,age  = ('alice', 29)
return [name,age] = ['alice', 29] 
----------------------------
5.局部变量 全局变量:
全局变量 定义在函数外部一级代码的变量 全局能用 上下顺序
局部变量 就是指定义 在函数里 的变量 只能在局部生效 
函数一旦完毕,局部变量内存地址就消失
在函数内部,可以引用 全局变量
如果,全局和局部 都有一个变量 叫name 函数查找变量的顺序是由内而外的
就是想--函数里面修改全局变量
global name 函数里面修改全局变量 
实际开发不用 global  因为其他函数也会用
如果全局变量是列表,字典,元组里面包含的列表 可以被修改 ,被修改的是某个元素,整体的不能被修改
names = ['alice','gril','alex']
def change_name():
    # names = ['alice','girl']
    print(names)
    del names[2]
    names[1] = '女孩'
    # global names
    # names=[1,2,3]
    print(names)
change_name()
print(names)
----------------------------
6.嵌套函数: 函数里嵌套函数
#嵌套函数
def func1():
    print('alex')
    def func2():
        print('alice')
    func2()
# 1.func1() #alex
# func1()
# 2.func1() # alex alice # 1.函数内部可以再次定义函数  2.执行需要被调用
func1()
age = 19
def func1():
    # age = 73
    # print(age)
    global age
    def func2():
        # age = 84
        print(age)
    age = 24
    func2()
    # age = 12
# 3.func1()
func1()
print(age)
----------------------------
7.作用域 :python中一个函数就是一个作用域(JavaScript),局部变量放置在其作用域中 
代码定义完成后,作用域已经生成,作用域链向上查找,函数名是可以当成返回值的!
def func1():   
   age = 12  
   print(age) 
   def fun2():
     age = 32
     print(age)
age = 18
def func1():
   age = 73
   def func2():
     print(age)
   return func2
val = func1()
val()
--------------------------------
8.匿名函数,能实现到 三元运算 在复杂就不行了 
匿名函数和其他的方法 搭配的使
匿名函数的作用:
   1.节省代码量
   2.看着高级
def calc(x,y):
    return x*y
func = lambda x,y:x*y  #声明一个匿名函数 
print(func(3,8))  
 
def calc(x,y):
    if x < y:
        return x*y
    else:
        return x/y
# func = lambda x,y:x*y  #声明一个匿名函数
func = lambda x,y: x*y if x < y else x/y     #声明一个匿名函数
print(calc(16,8))
print(func(16,8))
------------------------
data = list(range(10))
print(data)
# for index,i in enumerate(data):
#     data[index] = i*i
# print(data)
def f2(n):
    return n*n
# print(list(map(f2,data)))
print(list(map(lambda x,:x*x,data)))
---------------------------------
9.高阶函数 
变量可以指向函数
函数的参数能接受变量
那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数;
总结:只需要满足任意一个条件,即是高阶函数:
1.接受一个或多个函数作为输入
2.return返回另外一个函数
def func(x,y):
    return x+y
def calc(x):
    return x
f = calc(func)
print(f(2,3))
---------------------------------
10.递归 
跟循环的效果一样
递归的用途:
  递归 函数里面自己调自己
  不知道什么时候能结束这个循环
# 10/2 不断的除,直到不能除为止,打印每次结果
n = 10
while True:
    n = int(n/2)
    print(n)
    if n ==0:
        break
def calc(n):
    n = int(n/2)
    # print(n)
    return n
r1 = calc(10)
r2 = calc(r1)
r3 = calc(r2)
print(r3) 
 
# 递归 函数里面自己调自己
import sys
print(sys.getrecursionlimit()) #递归1000层 python 给了限制
def calc(n):
    n = int(n/2)
    print(n)
    calc(n) 
calc(10) 
------递归执行过程1层1层进,一层一层退-----
def calc(n):
    n = int(n/2)
    print(n)
    if n > 0:
        calc(n)
    print(n)
calc(10)
5
2
1
0
0
1
2
5
--------递归的返回值-------
def calc(n,count):
    print(n,count)
    if count < 5:
        return calc(n/2,count+1)
    else:
        return n
res = calc(188,1)
print('res=',res)
188 1
94.0 2
47.0 3
23.5 4
11.75 5
res= 11.75
递归总结:
 1.必须有一个明确的结束条件
 2.每次进入更深一层递归时,问题规模相比上次递归都应有所减少
 3.递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈stack这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧,由于栈的大小不是无限的,所以,递归调用的过多,会导致栈溢出。)
堆栈参考:http://www.cnblogs.com/lln7777/archive/2012/03/14/2396164.html
---------------------------------------------
函数内置方法:
参考地址:https://docs.python.org/3/library/functions.html?highlight=built#ascii
abs() 
dict() 
help() 
min() 
sorted() 多个参数
sorted(d.items,key=lambda x:x[1],reverse=True)
eval(f) f字符串转代码 
eval('print('hello world')')    //eval() 只能处理单行代码  有返回值 
exec(code) 能执行多行代码  没有返回值 
ord('a') = 97 
chr(97)='a' 
sum() 
bytearray() 字符串不可被修改 通过它就可被修改
list(map(lambda x:x*x,(1,2,3,4,5))) 
list(filter(lambda x:x>3,[1,2,3,4,5]))  //过滤
reduce  import functools 
functools.reduce(lambda x,y:x+y, [1,2,3,4,6678,4,2],3)
pow()
s="" 
print(s)
print(s,end='|')
print(s,sep='->') 
print(msg,'',sep='|',end='',file=f)
callable() 判断一个东西是否可调用 判断是否是对象 
vars() 当前多前的变量
locals() 打印函数的局部变量 
globals() 打印全局变量
repr() 显示形式变成字符串
zip()
round(1,2333,2)
delattr hasattr getattr setattr  
hash('abc') 
memoryview() 大数据进行copy形成内存映射
set() 列表集合
---------------------------------------------
总结:
1.函数
2.参数
3.非固定参数
4.函数的返回值
5.局部变量 全局变量
6.嵌套函数
7.作用域
8.匿名函数
9.高阶函数
10.递归
11.函数内置方法
                
            
        
浙公网安备 33010602011771号