遗漏知识点 函数和lambda表达式

Python遗漏知识点三 函数和lambda表达式

为函数提供文档:

def my_func(x, y):
	'''
	获取两个数值中较大数
	'''
	z = x if x>y else y
	return z


help(my_func)
print(my_func.__doc__)

python函数可以返回多个值,Python会自动将多个返回值封装成元组;Python提供序列解包功能,直接使用多个变量接受函数返回的多个值。

s, avg = sum_and_avg(my_list)
print(s)
print(avg)

函数的关键字:

  1. 位置参数:按照位置来传递参数

  2. 关键字参数:关键字参数和位置参数混合使用,关键字参数必须位于位置参数之后

    print(girth(4.2, width = 3.5))

  3. 参数默认值

     # 形参名 = 默认值
     def say_hi(name = '小明', message = '欢迎光临'):
     	print(name, '你好')
     	print('消息是:', message)
     
     
     say_hi()
     say('小黑', '下次光临')
    

由于python规定调用函数时关键字参数必须位于位置参数之后,因此在定义函数时指定默认值的参数(关键字参数)必须位于没有默认值的参数值之后

	def printTriangle(char, height = 5)
		pass
  1. 参数收集 (个数可变参数)
    python允许在形参前面加(*),这样就意味着可以接受多个参数值,多个参数值被当成元组传入。

     def test(*books, num):
     	print(books)
     	for i in books:
     		print(b)
     	print(num)
     # 可变参数位于第一个位置,那么后面的参数需要以关键字参数形式传递,否则会被归于可变参数中	
     test('a', 'b', 'c', num = 20)
    

    python会将多个关键字参数收集成字典。需要在形式参数前面添加两个星号。

     def test(x, y, z = 3, *book, **scores):
     	print(x,  y, z)
     	print(books)
     	print(scores)
     	
     
     test(1, 2, 3, '高数上', '高数下', '线代', 语文 = 100, 数学 = 99)	# 注意关键字参数传递方式
    
  2. 逆向参数收集
    指的是在程序已有列表、元组、字典等对象的前提,把他们的元素‘拆开’后给函数的参数。
    逆向参数收集需要在传入的列表、元组参数之前添加一个星号,在字典参数之前添加两个星号。

     def test(name, message):
     	print('用户是:', name)
     	print('欢迎信息:', message)
    
    
     my_list = ['xiaoming', 'welcome']
     test(*my_list)
    

实际上,即使是支持收集的参数,如果程序需要将一个元组传递给该参数,那么同样需要使用逆向收集
	def foo(name, *num):
		print('name参数:', name)
		print(nums参数:, nums)
		
		
	my_tuple = (1, 2, 3)
	foo('小明', *my_tuple)
字典也支持逆向收集,使用在实际参数前面加两个星号
	def test(book, price, information):
		print('书名:', book, '价格:', price)
		print(information)


	my_dict = {'book': '高数上', 'price': 26, 'information': '同济出版'}
	test(**my_dict)

注意:字典逆向收集类似于关键字参数,所以字典的key需要与函数的形式参数名对应而不能随便定义


Python参数传递机制都是值传递。就是讲实际参数的副本(复制品),传入函数中,而参数本身不受影响。
主函数有一个栈区,自定义的函数有一个栈区,执行自定义函数的时候,把实际参数的值复制一份到自定义函数栈中操作处理。
对于==可变对象==,也是使用值传递。但是定义一个可变对象,内存中有个两个东西:对象本身和指向该对象的引用变量。引用变量也就是一个指针,它保存了可变对象的地址值。因此,传递给自定义函数的也是地址值,所以主函数和自定义函数会引用到同一个字典对象。


变量的作用域:
globals()、locals()、vars(object)

  • 全局范围内调用globals()和locals()函数都会得到所有全局变量组成的字典。
  • 任意位置调用globals()都会的到所有全局变量字典。
  • var(object)得到的是指定对象范围内所有变量组成的变量字典,如果不传入object参数,vars()作用和locals()作用完全相同。
  • 使用gloabls()和locals()获得的全局范围的变量字典可以修改,会真正改变全局变量本身;但是通过locals()获取的局部范围内的变量字典,及时对它修改也不会影响局部变量。

全局变量默认可以在所有函数内被访问,但如果在函数中定义了与全局变量同名的变量就会发生局部变量遮蔽全局变量的情形。
name = ‘xiaoming’
def test():
print(name)
name = ‘laowang’ # 报错,显示局部name变量没有被定义

	test()

解决方法:

  1. 访问被遮蔽的全局变量
    name = ‘xiaoming’
    def test():
    print(globals()[‘name’])
    name = ‘laownag’

     test()
     print(name)
    
  2. 在函数中声明全局变量
    name = ‘xiaoming’
    def test():
    global name
    print(name)
    name = ‘laowang’ # 把全局变量改变了

     test()
     print(name)
    

封闭函数与局部函数概念:

	def foo():
		name = 'laowang'
		def bar():
			nonlocal name
			print(name)
			name = '小明'
		bar()
		
		
	foo()
  • nonlocal与local功能类似,区别只是global用于访问全局变量,而nonlocal用于声明访问当前局部函数所在的封闭函数内的局部变量

函数的高级内容(函数式编程):

  1. 使用函数变量
  2. 使用函数作为函数形参
  3. 使用函数作为返回值

局部函数与lambda函数:
lambda表达式只能是单行表达式;lambda本质就是匿名的单行函数体的函数。

	def get_math_func(type):
		result = 1
		if type == 'square':
			return lambda x: x * x
		elif type == 'cube':
			return lambda x: x*x*x
		else:
			return lambda x: (1+x)*x/2
	
	
	math_func = get_math_func('cube')
	print(math_func(3))

	x = map(lambda x: x*x, range(8))
	print([e for e in x])
	
	y = map(lambda x: x*x if x%2 == 0 else 0, range(1, 8))
	print([e for e in y])
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章