# def test01():
# msg = "sjy"
#
# def test02():
# msg = "yue"
# print(msg)
# return msg
#
# def test03():
# msg = "yi"
# print(msg)
# return 1,2,"sd",[1,2]
#
# t1 = test01()
# t2 = test02()
# t3 = test03()
# print(t1) #当函数中没有返回值时,打印这个函数,会返回一个none
# print(t2) #当函数中只有一个返回值时,打印这个函数直接返回这个值
# print(t3) #当函数返回值有多个,则打印这个函数时这些值会放在一个元组中返回
# def calc(x,y): #x,y为函数参数,属于形参,只有在函数在被调用时才会被分配内存,且调用结束后,立即释放占用的内存
# res = x ** y
# return res #函数运行到return时,函数结束,却必须要return一个值,否则调用这个函数时会返回一个none
# res = calc(2,3) #调用函数时,如果用位置参数,则参数位置一一对应,缺一,多一都不行
# test = calc(y = 5,x = 2) #但用关键字参数时,则不用一一对应,但也不能缺一或多一
# print(res)
# print(test)
# def test(x,*args): #当参数前带一个 * 时,代表将剩余的多个参数值放在一个元组里
# print(x)
# print(args) #带 * 时建议参数名用args
# # test(1,2,34,5,6) #此时1赋值给x,剩下的参数值都赋值给arge
# test(1,*[2,3,4]) #当赋值的参数有列表或元组时,若在列表前加*,则列表遍历迭代后传给上面的参数args,不加*,则作为一个整体传过去
# def test(x,**kwargs): #当参数前面带有**时,代表将按顺序传递后,关键字/值按照字典的形式返回
# print(x)
# print(kwargs) #带 ** 时,参数名建议用kwargs
# test(1,y = 2, z = 3) #注意这种形式 ** kwargs参数必须是关键字/值成对的出现,根据上面做好位置对应
# def test(x,*args,**kwargs): #当使用多个类型参数是,按照这个参数顺序,
# print(x)
# print(args)
# print(kwargs)
# test(1,2,3,4,5,y = 12,z = 23)
"""
函数参数的几种类型:
func(value):常规参数,位置参数,按照位置一一对应
func(name = value):关键字参数,通过关键字匹配
func(*sequence):按照顺序传递参数,将最后剩余的值放到一个元组中传递过去
func(**dict):按照成对的关键字/值传递
"""
# NAME = "sjy" #这里定义的是全局变量
# def change_name1():
# global NAME #使用global时,就将该变量变成全局变量,这时即使在函数内对它赋值,他也是全局变量
# NAME = "yue" #当前面没有用global时,这里定义的是局部变量,对全局变量不产生影响
# print("change_name1",NAME)
# def change_name2():
# name = "yi"
# print("change_name2",name)
# change_name2() #先调用哪个函数,则先运行这个函数,并不受函数在哪个位置,即使这个函数位置在别的函数后面
# change_name1() #只有调用了函数,才会有结果产生,不调用,则不会有结果
# print(NAME)
# NAME = "sjy"
# def xinming():
# name = "yue"
# print(name)
# def nicheng(): #嵌套函数,只用当上一层函数调用了这个内部函数时,才会运行
# print("yi")
# def age(): #同样是嵌套,在上一层调用时才会运行
# print("25")
# age() #注意函数的调用代码是要放在在所有嵌套函数写完之后
# nicheng() #如果把函数调用放在下一个嵌套函数之前会破坏嵌套,会报错
# xinming()
# name = "sjy"
# def xinming():
# name = "yue" #定义局部变量
# def nicheng():
# global name #将嵌套的函数的变量变成全局变量,目的在于将全局变量修改
# name = "yi"
# nicheng() #调用嵌套函数,这个嵌套函数对全局变量发生改变,并未对外层函数修改
# print(name) #打印第一层函数值,这个值是上面定义的本地变量
# print(name) #打印全局变量
# xinming() #执行函数
# print(name) #在执行函数后,嵌套函数将全局变量改变了
# name = "sjy"
# def xinming():
# name = "yue" #定义局部变量
# def nicheng():
# nonlocal name #对外层函数的本地变量进行修改
# name = "yi"
# nicheng() #调用这个函数后,外层的函数本地变量发生了改变
# print(name) #此时这个name发生了改变
# print(name)
# xinming()
# print(name)
"""
全局变量:在模块顶层定义的变量
局部变量:在子程序中定义的变量,例如函数中定义的变量就是本地变量
为了方便区分,全局变量用大写,局部变量用小写
变量名解析顺序遵循LEGB法则:本地变量→函数内→全局变量→内置变量
现在建议用LNGB:本地→嵌套函数的nonlocal→全局→内置
把局部变量变成全局变量使用 global,注意global要放在变量上面行
如果函数中没有global关键字,则只能对可变的全局变量进行修改,不能对任何全局变量重新赋值,赋值则就是局部变量
若想对函数嵌套的变量进行修改用 nonlocal
函数里面可以在嵌套函数,并且有外到内一步一步编译,注意内部函数调用时才会执行,没有调用,不会执行
"""
"""
函数即变量:函数名相当于一个变量名,函数的过程内容相当于一个字符串
风湿理论:函数的前向调用,在调用一个函数时,必须先定义这个函数,如果在调用之后再定义函数,则会报错
对于Python来说,代码从上往下执行,遇到变量,函数就会为其开辟一个内存来存放它,在需要时则直接调用
如果在函数还未建立就调用,则程序就会不知道从哪里调用,找不到函数所在的内存,就会报错
"""
# def foo():
# print("from in foo")
# bar()
# foo() #此时调用foo函数时,foo函数里的bar函数还未定义,程序找不到这个函数所在的位置
# def bar():
# print("from in bar")
"""
递归函数:直接或间接进行调用自身循环的函数,必须要有明确的结束条件
效率不高,容易导致栈溢出,因为递归函数在循环时会存在等待结果的过程,这个过程需要内存来存储
"""
# def calc(n):
# print(n)
# if int(n/2) == 0: #判断符合条件,根据条件返回值
# return n
# return calc(int(n/2))
# calc(10)
#递归函数循环调用自身
# import time #导入时间模块
# person_list = ["sjy","yue","yi","xi","su"]
# def ask_way(person_list):
# print("--" * 60)
# print("HI,问一下这个地方" )
# if person_list == []:
# return "没人知道" #循环结束的if条件
# person = person_list.pop(0)
# if person == "xi":
# return "%s:我知道,这个是在那里" %person #递归循环结束的if条件
# else:
# print("%s:我不知道,我可以帮你问问%s" % (person,person_list[0]))
# time.sleep(1) #设置时间间隔为1秒
# res = ask_way(person_list) #得到函数执行结果,若则这个结果不码字结束条件,将再进入函数,循环
# print("%s结果:%res" % (person,res))
# return res #满足上面的结束条件后,返回结果
# print(ask_way(person_list))
"""
匿名函数:格式:lambda x : x + 1 →冒号左边的x 是参数,右边的是函数过程
"""
# def calc(x):
# return x * 2
# print(calc(5))
#
# func = lambda x : x * 2 #这个等同于上面的函数
# print(func(5)) #要现将其赋值给一个变量,才能打印这个函数的值,但一般不赋值,它不是单独使用,与其他配合使用
# name = "sjy"
# func = lambda x : name + "_yue"
# print(func(name))
"""
map函数:map(func,array) 对可迭代对象的每个元素进行修改后,再将每个修改后的元素放在一个列表用返回
→ func是一个函数调用,可直接用lambda匿名函数,也可以用其他定义的函数,array是可迭代对象
"""
# num_list = [1,3,7,23,12,2]
# def add_one(x):
# return x + 1
# def reduce_one(x):
# return x - 1
# def mi(x):
# return x ** 2 #设置一些方法调用
# def calc(func,change_list): #设置参数,参数为上面的方法调用,以及要修改的量
# ret = []
# for i in change_list:
# res = func(i) #在函数中调用上面设置的方法
# ret.append(res)
# return ret
# print(calc(mi,num_list)) #调用函数后,填上参数
# print(calc(lambda x : x ** 2,num_list)) #可以在函数调用时在方法参数的位置上直接用匿名函数,简化过程
# print(calc(add_one,num_list))
# print(calc(reduce_one,num_list))
# f = map(lambda x : x ** 2,num_list) #利用map函数可得到上述所使用的效果
# print(f) #注意这里打印得到的是map函数的地址
# print(list(f)) #要把结果在传到需要的类型才可以出现最终结果
# ret = [] #其过程如下的循环操作
# for i in f:
# ret.append(i)
# print(ret)
"""
reduce函数:在Python3.0后面版本必须先导入reduce模块
reduce(func,array,init=None) 对可迭代对象的元素从左到右依次进行函数运算得到一个最终值
func需要调用的函数,array可迭代对象,init初始值,可以设置,可以不设置
"""
# from functools import reduce #导入reduce模块
# num_l = [1,3,6,10]
# f = reduce(lambda x,y:x*y,num_l,10) #执行函数。填上参数,和map不同这个直接得到一个值,map是每个元素修改再放到一个列表中
# print(f) #直接打印这个值就行,不需要再放在一个类型中,具体执行过程如下程序
# def chen(x,y): #reduce执行逻辑
# return x*y
# def calc(func,array,init=None):
# if init is not None:
# res = init
# else:
# res = 1
# for i in array:
# res = func(res,i)
# return res
# print(calc(chen,num_l))
"""
filter函数:filter(func,array) 筛选出需要的元素,再将这些需要的返回到一个列表中。 参数是函数,可迭代对象
"""
# num_l = [1,3,6,23,56,2]
# def oushu(x):
# return x % 2 == 0
# f = filter(oushu,num_l) #过滤不需要的元素,返回需要的
# print(f) #这里返回的是可迭代对象,与map类似
# print(list(f)) #需要把结果放在类中
# def calc(func,array): #filter执行逻辑
# ret = []
# for i in array:
# if func(i): #if x % 2 == 0
# ret.append(i)
# return ret
# print(calc(oushu,num_l))
"""
内置函数
"""
# print(abs(2)) #求绝对值
# all([1,2,""]) #判断所有值的bool值,相当于and,参数只能是一个参数,不能放两个
# any([23,3]) #相当于or
# name = "你好"
# print(bytes(name,encoding="utf-8")) #对字符串进行二进制的转换
# print(bytes(name,encoding="utf-8").decode("utf-8")) #注意格式,是转换成二进制,然后再转换,如下效果
# b = bytes(name,encoding="utf-8") #注意转成什么样的格式,转换回来也要是什么格式,默认utf-8格式
# print(b.decode("utf-8"))
# dir(all) #打印某一个对象下的各种方法
# divmod(10,3) #分页,第一个参数代表总的内容,第二个代表设置每页有多少内容
# 得到的结果也有两个参数,第一个参数是分了多少页,第二个参数是分过这些页之后还有剩几个内容不能达到每页应有的总数
# globals() #显示当前的全局变量
# locals() #显示当前的局部变量
# print(zip(("a","b","c"),(1,2,3,4))) #zip将第一个,第二个两个可迭代对象建立一一对应的关系
# print(list(zip(("a","b","c"),(1,2,3,4)))) #需要将对应关系放进一个才能将值打印出来
# age_dic = {"age1":18,"age3":23,"age2":56,"age4":33}
# print(max(age_dic.values())) #max取最大值,数值直接按最大取
# print(max(age_dic)) #字符串从左到右按每字符进行比较,当读到某个字符大于其他的,那么这个字符串就是最大的
# print(list(max(zip(age_dic.values(),age_dic.keys()))))
# 利用zip函数先将字典建立一个元组形式的对应关系,再用max得到最大值,这时可将键值对都都得到
# l = [(5,"e"),(2,"a"),(1,"c"),(3,"b"),(4,"d")]
# print(max(l)) #判断大小时顺序判读,类似文件按名称大小排列时的规则
#注意不能将不同的类型的进行比较
# d = [
# {"name1":"alex","age":720},
# {"name2":"sjy","age":25},
# {"name3":"yue","age":7245}
# ]
# print(max(d,key=lambda dic:dic["age"])) #相当于将列表先循环然后再比较内部的容
#min 取最小值 与 max 用法相同
#sort 排序,按照从小到大排序,方法与min , max 相同
# __import__() #导入字符串类型
# import #导入模块