赞
踩
- #!/usr/bin/python3
- # 函数的文档
- def doc_demo(x,y):
- '''
- 输入x,y
- 获取x、y中的较大值
- '''
- z = x if x>y else y
- return z
- # help(doc_demo)
- print(doc_demo.__doc__)
- # print(help(doc_demo)) # pycharm执行会报错,命令行执行正常
- # 多个返回值,自动封装为元组
- def sum_and_avg(list):
- sum = 0
- count = 0
- for e in list:
- # 如果元素e是数值
- if isinstance(e, int) or isinstance(e, float): # isinstance()函数 判断是不是指定类型的实例
- count += 1
- sum += e
- return sum, sum / count
- my_list = [20, 15, 2.8, 'a', 35, 5.9, -1.8]
- # 获取sum_and_avg函数返回的多个值,多个返回值被封装成元组
- tp = sum_and_avg(my_list) #①
- print(tp)
- # 使用序列解包来获取多个返回值
- s, avg = sum_and_avg(my_list) #②
- print(s)
- print(avg)
-
- # 递归函数:函数内部不断调用自身,必须保证有约束条件(某个时刻返回值是确定的),不然会无穷递归类似于死循环
- def fn(n):
- if n==0:
- return 1
- elif n==1:
- return 4
- else:
- return 2*fn(n-1)+fn(n-2)
- print(fn(10))
- # 形参:形式参数,在函数的定义处定义的参数
- # 实参:实际参数,在函数调用处定义的参数
- # 关键字(keyword)参数
- def girth(key,word):
- return (key,word)
-
- print(girth(1,2))
- print(girth(key=1,word=2))
- # print(girth(1,word=2)) # 混合使用关键字参数和位置参数,位置参数必须要在关键字参数之前
-
- # Python要求将默认值参数定义在形参的最后
- def say_hi(name,message='456'):
- return (name,message)
-
- def test(x,y,z=3,*name,**value): # 最多支持一个可变参数*和**可变关键字参数,此时可变参数会作为元组输入,可变关键字参数作为词典传入
- print('name',name)
- print('z',z)
- for i in name:
- print('i的值是%s'%(i))
- print('value',value)
-
- test(1,2,3,'123',4,'567',value1=1,value2=2)
- test(1,2,value1=1,value2=2) # 若想默认值参数z生效,则只能将前面的位置参数传入,后面使用关键字参数
-
- # 可变个数参数:本质是多个参数作为元组传入;位置可前可后,一个函数只能带一个普通的参数收集的形参
- def autoDemo(a,*b):
- print(a)
- print()
- for i in b:
- print(i,end=",")
- autoDemo(1,2,3,4,5,6,7)
-
- # 逆向参数收集:将sequence中的元素拆开传入函数,列表和元组为*;字典**,会以关键字参数的方式传入
- def reversal(name,*values):
- print('name的参数',name)
- print('valuses的参数',values)
- listdemo=['name1',1,2,3]
- reversal(*listdemo)
-
- a,b=6,7
- a,b=b,a #右边会封包,然后传给左边
- print(a,b)
-
- '''
- 函数的参数传递机制
- python函数的参数传递方式为值传递:将实际参数的副本传入函数,而参数本身不受影响
- 指针变量(引用变量)
- 1、程序开始创建了一个字典对象,并定义了一个dw引用变量指向字典对象,这意味着此时内存中有两个东西:对象本身和指向该对象的引用变量。
- 2、主程序中的 dw 是一个引用变量(也就是一个指针),它保存了字典对象的地址值,当把 dw 的值赋给swap()函数的dw参数后,就是让swap()的dw参数也保存这个地址值,即也会引用到同一个字典对象。
- 1、不管什么类型的参数(实参),在Python函数中对参数直接使用"="符号赋值是没用的 ,直接使用“=”符号赋值并不能改变参数(实参)。
- 2、如果需要让函数修改某些数据,则可以通过把这些数据包装成列表、字典等可变对象,然后把列表、字典等可变对象作为参数传入函数,在函数中通过列表、字典的方法修改它们,这样才能改变这些数据。
- '''
- # 变量值参数输入不会改变
- def swap(a , b) :
- # 下面代码实现a、b变量的值交换
- a, b = b, a
- print("swap函数里,a的值是", \
- a, ";b的值是", b)
- a = 6
- b = 9
- swap(a , b)
- print("交换结束后,变量a的值是", \
- a , ";变量b的值是", b)
- # 指向性参数传入可改变
- def swap(dw):
- # 下面代码实现dw的a、b两个元素的值交换
- dw['a'], dw['b'] = dw['b'], dw['a']
- print("swap函数里,a元素的值是",\
- dw['a'], ";b元素的值是", dw['b'])
- # 把dw直接赋值为None,让它不再指向任何对象
- dw = None
- dw = {'a': 6, 'b': 9}
- swap(dw)
- print("交换结束后,a元素的值是",\
- dw['a'], ";b元素的值是", dw['b'])
-
- # 变量的作用域:变量的作用范围被称为它的作用域
- # 局部变量:在函数内部作用
- # 全局变量:全局都可作用
- # globals():该函数返回全局范围内所有变量组成的“变量字典”
- # locals():该函数返回当前局部范围内所有变量组成的“变量字典”
- # vars(object):获取在指定对象范围内所有变量组成的“变量字典”。如果不传入object参数,vars()和 locals()的作用完全相同。
- # 通过locals()或者globals()获取的全局变量可以被修改,并影响到变量本身;通过locals()获取的局部变量即使修改也不会影响到局部变量
- def test():
- age = 20
- # 直接访问age局部变量
- print(age) # 输出20
- # 访问函数局部范围的“变量数组”
- print(locals()) # {'age': 20}
- # 通过函数局部范围的“变量数组”访问age变量
- print(locals()['age']) # 20
- # 通过locals函数局部范围的“变量数组”改变age变量的值
- locals()['age'] = 12
- # 再次访问age变量的值
- print('xxx', age) # 依然输出20
- # 通过globals函数修改x全局变量
- globals()['x'] = 19
- x = 5
- y = 20
- print(globals()) # {..., 'x': 5, 'y': 20}
- # 在全局访问内使用locals函数,访问的是全局变量的“变量数组”
- print(locals()) # {..., 'x': 5, 'y': 20}
- print(globals())
- # 直接访问x全局变量
- print(x) # 5
- # 通过全局变量的“变量数组”访问x全局变量
- print(globals()['x']) # 5
- # 通过全局变量的“变量数组”对x全局变量赋值
- globals()['x'] = 39
- print(x) # 输出39
- # 在全局范围内使用locals函数对x全局变量赋值
- locals()['x'] = 99
- print(x) # 输出99
- print(test())
- print(x) # x可以被函数内的globals函数修改
-
- # Python语法规定:在函数内部对不存在的变量赋值时,默认就是重新定义新的局部变量。因此这行代码相当于重新定义了name局部变量,\
- # 这样name全局变量就被遮蔽(不在函数内部作用)了,所谓的局部变量遮蔽全局变量,所以下面这段会报错。
- # name='123'
- # def a123():
- # print(name) # 会报错,因为下一行赋值导致全局变量name被局部变量遮蔽,从而报未定义前的引用
- # name = 'afv'
- # a123()
- # print(name)
-
- # 函数中访问遮蔽变量的两种方式
- # 1、通过global()函数访问
- name='123'
- def accessHide1():
- print(globals()['name'])
- name='456'
- accessHide1()
-
- # 2、通过global在函数中定义全局变量:global name声明以后
- # 程序会把 name变量当成全局变量,这意味着accessHide2()函数后面对name赋值的语句只是对全局变量赋值,而不是重新定义局部变量
- name='charters'
- def accessHide2():
- global name
- print(name)
- name='landel'
- accessHide2()
-
- # 局部函数:局部函数对外部是隐藏的,只能在其封闭(enclosing)函数内有效
- def get_mathCalc(module,n1):
- def square(n):
- return n*n
- def cube(n):
- return n*n*n
- def factorial(n):
- result=1
- for i in range(2,n+1):
- result *= i
- # 在函数内调用局部函数
- if module == 'square':
- return square(n1)
- elif module == 'cube':
- return cube(n1)
- elif module == factorial:
- return factorial(n1)
- print(get_mathCalc('square',2))
- # 局部函数变量遮蔽
- def hideLocal1():
- name='charters'
- def local1():
- # print(name) # 受后面影响,会定义name为局部变量,函数中的name变量被遮蔽导致报错
- name=123
- # 在局部函数中访问遮蔽变量的方式
- def hideLocal2():
- name='charters'
- def local2():
- nonlocal name # 这里nonlocal和global的作用相似,看字面意思
- print(name)
- local2()
- hideLocal2()
-
- # 函数作为变量使用
- # 函数也是一种值:所有函数都是function对象,把函数赋值给变量,可以通过变量来调用它
- def pow(base, exponent) :
- result = 1
- for i in range(1, exponent + 1) :
- result *= base
- return result
- # 将pow函数赋值给my_fun,则my_fun可当成pow使用
- my_fun = pow
- print(my_fun(3 , 4)) # 输出81
- # 定义一个计算面积的函数
- def area(width, height) :
- return width * height
- # 将area函数赋值给my_fun,则my_fun可当成area使用
- my_fun = area
- print(my_fun(3,4)) # 输出12
-
- # 函数可以作为形参传入函数:可以动态改变程序代码-实现在函数内部动态调用不同函数
- # 定义函数类型的形参,其中fn是一个函数
- def map(data, fn) :
- result = []
- # 遍历data列表中每个元素,并用fn函数对每个元素进行计算
- # 然后将计算结果作为新数组的元素
- for e in data :
- result.append(fn(e))
- return result
- # 定义一个计算平方的函数
- def square(n) :
- return n * n
- # 定义一个计算立方的函数
- def cube(n) :
- return n * n * n
- # 定义一个计算阶乘的函数
- def factorial(n) :
- result = 1
- for index in range(2, n + 1) :
- result *= index
- return result
- data = [3 , 4 , 9 , 5, 8]
- print("原数据: ", data)
- # 下面程序代码3次调用map()函数,每次调用时传入不同的函数
- print("计算数组元素的平方")
- print(map(data , square))
- print("计算数组元素的立方")
- print(map(data , cube))
- print("计算数组元素的阶乘")
- print(map(data , factorial))
- # 获取map的类型
- print(type(map))
-
- # 函数作为返回值:动态接受不同的局部函数
- def get_math_func(funciton):
- def square(n):
- return n*n
- def cube(n):
- return n*n*n
- def factorial(n):
- result=1
- for i in range(2,n+1):
- result *= i
- return result
- # 返回子局部函数
- if funciton == 'square':
- return square
- elif funciton == 'cube':
- return cube
- elif funciton == 'factorial':
- return factorial
- # 调用函数,接受局部函数
- math1=get_math_func('square')
- print(math1(2))
- math2=get_math_func('cube')
- print(math2(3))
- math3=get_math_func('factorial')
- print(math3(3))
-
- # 使用lambda表达式代替局部函数:1、局部函数名没有意义,2、单行表达式
- # 格式:lambda [parameter_list] : 表达式
- # lambda 表达式依然有如下两个用途
- # 对于单行函数,使用lambda表达式可以省去定义函数的过程,让代码更加简洁。
- # 对于不需要多次复用的函数,使用lambda表达式可以在用完之后立即释放,提高了性能
- def get_math_func1(function):
- if function=='square':
- return lambda n:n*n
- elif function=='cube':
- return lambda n:n*n*n
- elif function=='factorial':
- return lambda n:n*(n+1)/2
- math1=get_math_func1('square')
- print(math1(2))
- math2=get_math_func1('cube')
- print(math2(3))
- math3=get_math_func1('factorial')
- print(math3(5))
- # 通过lambda表达式来调用Python置的map()函数
- x=map(lambda n:n*n,range(8))
- print(x) #object
- print([e for e in x ])
- y=map(lambda n:n*n if n%2==0 else 0,range(8))
- print([e for e in y])
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。