首页 > 其他分享 >3_函数

3_函数

时间:2022-10-17 18:00:22浏览次数:47  
标签:return 函数 形参 作用域 参数 print

1. 函数简介(function)

​ - 函数也是一个对象

​ - 对象是内存中专门用来存储数据的一块区域

​ - 函数可以用来保存一些可执行的代码,并且可以在需要时,对这些语句进行多次的调用

​ - 创建函数:

​ def 函数名([形参1,形参2,...形参n]) : define:定义

​ 代码块

​ - 函数名必须要符和标识符的规范

​ (可以包含字母、数字、下划线、但是不能以数字开头)

​ - 函数中保存的代码不会立即执行,需要调用函数代码才会执行

​ - 调用函数:

​ 函数对象()

​ - 定义函数一般都是要实现某种功能的

2. 函数的参数

​ - 在定义函数时,可以在函数名后的()中定义数量不等的形参,

​ 多个形参之间使用,隔开

​ - 形参(形式参数),定义形参就相当于在函数内部声明了变量,但是并不赋值

​ - 实参(实际参数)

​ - 如果函数定义时,指定了形参,那么在调用函数时也必须传递实参,

​ 实参将会赋值给对应的形参,简单来说,有几个形参就得传几个实参

3. 参数的传递方式

1、定义形参时,可以为形参指定默认值

指定了默认值以后,如果用户传递了参数则默认值没有任何作用。如果用户没有传递,则默认值就会生效,如:

def fn(a = 5 , b = 10 , c = 20):

​ print('a =',a)

​ print('b =',b)

​ print('c =',c)

fn(1 , 2 , 3)

fn(1 , 2)

fn()

2、实参的传递方式

A、位置参数

位置参数就是将对应位置的实参复制给对应位置的形参

第一个实参赋值给第一个形参,第二个实参赋值给第二个形参 。。。

fn(1 , 2 , 3)

B、关键字参数

关键字参数,可以不按照形参定义的顺序去传递,而直接根据参数名去传递参数

fn(b=1 , c=2 , a=3)

print('hello' , end='')

位置参数和关键字参数可以混合使用

混合使用关键字和位置参数时,必须将位置参数写到前面

fn(1,c=30)

3、函数在调用时,解析器不会检查实参的类型。实参可以传递任意类型的对象,但是,如果类型不匹配会报错哦。

4、在函数中对形参进行重新赋值,不会影响其他的变量

​ 但如果形参执行的是一个对象,当我们通过形参去修改对象时

​ 会影响到所有指向该对象的变量

若不希望改变对象,可以有以下传递方法:

fn4(c.copy())

fn4(c[:])

也就是创建一个副本再传递,是函数的形参指向的不是原来的对象而是副本对象

4. 不定长的参数

# 定义一个函数,可以求任意个数字的和

例子:

# 定义一个变量,来保存结果,遍历元组,并将元组中的数进行累加

def sum(*nums):

​ result = 0

​ for n in nums :

​ result += n

​ print(result)

# sum(123,456,789,10,20,30,40)

*号详解:

# 在定义函数时,可以在形参前边加上一个*,这样这个形参将会获取到所有的实参

# 它将会将所有的实参保存到一个元组

# a,b,*c = (1,2,3,4,5,6)

# *a会接受所有的位置实参,并且会将这些实参统一保存到一个元组中(装包)

def fn(*a):

​ print("a =",a,type(a))

# fn(1,2,3,4,5)

注意点:

# 1.带星号的形参只能有一个

# 2.带星号的参数,可以和其他参数配合使用

# 3.第一个参数给a,第二个参数给b,剩下的都保存到c的元组中,如:

# def fn2(a,b,*c):

# print('a =',a)

# print('b =',b)

# print('c =',c)

# 4.可变参数不是必须写在最后,但是注意,带*的参数后的所有参数,必须以关键字参数的形式传递,否则不起作用

如:

# 所有的位置参数都给a,b和c必须使用关键字参数

# def fn2(*a,b,c):

#fn2(1,2,b=3,c=4)

# print('a =',a)

# print('b =',b)

# print('c =',c)

# 5.如果在形参的开头直接写一个*,则要求我们的所有的参数必须以关键字参数的形式传递

def fn2(*,a,b,c):

​ print('a =',a)

​ print('b =',b)

​ print('c =',c)

# fn2(a=3,b=4,c=5)

#6. *形参只能接收位置参数,而不能接收关键字参数

**号详解:

# **形参可以接收其他的关键字参数,它会将这些参数统一保存到一个字典中

# 字典的key就是参数的名字,字典的value就是参数的值

# **形参只能有一个,并且必须写在所有参数的最后

def fn3(b,c,**a) :

​ print('a =',a,type(a))

​ print('b =',b)

​ print('c =',c)

# fn3(b=1,d=2,c=3,e=10,f=20)

*号和**号解包:

# 传递实参时,也可以在序列类型的参数前添加星号,这样他会自动将序列中的元素依次作为参数传递

# 这里要求序列中元素的个数必须和形参的个数的一致

如:

# 创建一个元组,通过*进行解包操作

t = (10,20,30)

# fn4(*t)

# 创建一个字典

d = {'a':100,'b':200,'c':300}

# 通过 **来对一个字典进行解包操作

fn4(**d)

5. 返回值

# 返回值,返回值就是函数执行以后返回的结果

# 可以通过 return 来指定函数的返回值

# 可以直接使用函数的返回值,也可以通过一个变量来接收函数的返回值

# return 后边可以跟任意的对象,返回值甚至可以是一个函数,例如:

def fn():

​ # return 'Hello'

​ # return [1,2,3]

​ # return {'k':'v'}

​ def fn2() :

​ print('hello')

​ return fn2 # 返回值也可以是一个函数

r = fn()

# print(r)

# 如果仅仅写一个return 或者 不写return,则相当于return None

def fn2() :

​ a = 10

​ return

# 在函数中,return后的代码都不会执行,return 一旦执行函数自动结束

def fn4() :

​ for i in range(5):

​ if i == 3 :

​ # break 用来退出当前循环

​ # continue 用来跳过当次循环

​ # return 用来结束函数

​ print(i)

print('循环执行完毕!')

# fn4()

# fn5 和 fn5()的区别

print(fn5) # fn5是函数对象,打印fn5实际是在打印函数对象 <function fn5 at 0x05771BB8>

print(fn5()) # fn5()是在调用函数,打印fn5()实际上是在打印fn5()函数的返回值 10

6. 文档字符串

Help函数

# help()是Python中的内置函数

# 通过help()函数可以查询python中的函数的用法

# 语法:help(函数对象)

# help(print) # 获取print()函数的使用说明

# 文档字符串(doc str)

# 在定义函数时,可以在函数内部编写文档字符串,文档字符串就是函数的说明

# 当我们编写了文档字符串时,就可以通过help()函数来查看函数的说明

# 文档字符串非常简单,其实直接在函数的第一行写一个字符串就是文档字符串

一般来说,用’’、” ”、‘’‘ ’‘’都可以,但是前两个只能写一行,而后面三引号可以写多行,一般用’’’ ’’’

在a后加:int代表a接收int型,而-> int代表返回值是int型,当然,这只是标记,并不会是a就是接收int型,它主要是起一个提示作用。

7. 作用域

# 作用域(scope)

# 作用域指的是变量生效的区域

# 在Python中一共有两种作用域

# 1、全局作用域

# - 全局作用域在程序执行时创建,在程序执行结束时销毁

# - 所有函数以外的区域都是全局作用域

# - 在全局作用域中定义的变量,都属于全局变量,全局变量可以在程序的任意位置被访问

#

# 2、函数作用域

# - 函数作用域在函数调用时创建,在调用结束时销毁

# - 函数每调用一次就会产生一个新的函数作用域

# - 在函数作用域中定义的变量,都是局部变量,它只能在函数内部被访问

# 3、变量的查找

# 当我们使用变量时,会优先在当前作用域中寻找该变量,如果有则使用,

# 如果没有则继续去上一级作用域中寻找,如果有则使用,

# 如果依然没有则继续去上一级作用域中寻找,以此类推

# 直到找到全局作用域,依然没有找到,则会抛出异常

# NameError: name 'a' is not defined

​ 简单的说,局部变量外部不能调,而局部变量可以调外部的全局变量,和java一样

#4、global关键字

# 如果希望函数内部的变量是全局变量,则需要使用global关键字,来声明变量

global a # 声明在函数内部的使用a是全局变量 global [ˈɡləʊbl] 全球的,整体的

8. 命名空间(namespace)

# 命名空间指的是变量存储的位置,每一个变量都需要存储到指定的命名空间当中

# 每一个作用域都会有一个它对应的命名空间

# 全局命名空间,用来保存全局变量。函数命名空间用来保存函数中的变量

# 命名空间实际上就是一个字典,是一个专门用来存储变量的字典

#1、locals()函数

# locals()用来获取当前作用域的命名空间,如果在全局作用域中调用locals()则获取全局命名空间,如果在函数作用域中调用locals()则获取函数命名空间,返回值是一个字典

scope = locals() # 当前命名空间

print(scope)

scope['c'] = 1000 # 向字典中添加key-value就相当于在全局中创建了一个变量(一般不建议这么做)

def fn4():

​ a = 10

​ # scope = locals() # 在函数内部调用locals()会获取到函数的命名空间

​ # scope['b'] = 20 # 可以通过scope来操作函数的命名空间,但是也是不建议这么做

# print(scope)

fn4()

2、# globals()函数

# globals() 函数可以用来在任意位置获取全局命名空间,一般用来在函数中获取全局命名空间,而在全局空间中是无法获取函数(局部)命名空间的。

9. 递归

引题:

# 尝试求10的阶乘(10!)

# 1! = 1

# 2! = 1*2 = 2

# 3! = 123 = 6

# 4! = 123*4 = 24

# 创建一个变量保存结果

# n = 10

# for i in range(1,10):

# n *= i

# print(n)

进阶:创建一个函数,可以用来求任意数的阶乘

def factorial(n):

​ '''

​ 该函数用来求任意数的阶乘

​ 参数:

​ n 要求阶乘的数字

​ '''

​ # 创建一个变量,来保存结果

​ result = n

​ for i in range(1,n):

​ result *= i

​ return result

# 递归式的函数

# 递归简单理解就是自己去引用自己!

# 无穷递归,如果这个函数被调用,程序的内存会溢出,效果类似于死循环

# def fn():

# fn()

# fn()

# 递归是解决问题的一种方式,它和循环很像

# 它的整体思想是,将一个大问题分解为一个个的小问题,直到问题无法分解时,再去解决问题

# 递归式函数的两个要件

# 1.基线条件

# - 问题可以被分解为的最小问题,当满足基线条件时,递归就不在执行了

# 2.递归条件

# - 将问题继续分解的条件

# 递归和循环类似,基本是可以互相代替的

用递归实现求任意数的阶乘功能:

def factorial(n):

​ # 基线条件 判断n是否为1,如果为1则此时不能再继续递归

​ if n == 1 :

​ # 1的阶乘就是1,直接返回1

​ return 1

​ # 递归条件

​ return n * factorial(n-1)

# print(factorial(10))

10. 高阶函数

# 接收函数作为参数,或者将函数作为返回值的函数是高阶函数

# 当我们使用一个函数作为参数时,实际上是将指定的代码传递进了目标函数

例子:实现一个函数,可以将列表中的偶数单独变成列表返回、大于5的数单独变成列表返回、3的倍数单独变成列表返回,这个函数思路是去接收函数实现,例子如下:

l = [1,2,3,4,5,6,7,8,9,10]

# 定义一个函数,用来检查一个任意的数字是否是偶数

def fn2(i) :

​ if i % 2 == 0 :

​ return True

​ return False

# 这个函数用来检查指定的数字是否大于5

def fn3(i):

​ if i > 5 :

​ return True

return False

# 这个函数用来检查指定的数字是3的倍数

# def fn4(i):

# if i % 3 == 0:

# return True

# return False

def fn(func , lst) :

​ '''

​ fn()函数可以将指定列表中的所有偶数获取出来,并保存到一个新列表中返回

​ 参数:

​ lst:要进行筛选的列表

​ '''

​ # 创建一个新列表

​ newlist = []

​ # 对列表进行筛选

​ for n in lst :

​ if func(n) :

​ newlist.append(n)

​ return newlist

# 1、filter()函数

# filter()可以从序列中过滤出符合条件的元素,保存到一个新的序列中,功能和用法就和上面例子fn函数一样。

# 参数:

# 1.函数,根据该函数来过滤序列(可迭代的结构)

# 2.需要过滤的序列(可迭代的结构)

# 返回值:

# 过滤后的新序列(可迭代的结构)

# 2、匿名函数 lambda

​ lambda /ˈlæmdə/ 匿名函数

# lambda函数表达式专门用来创建一些简单的函数,他是函数创建的又一种方式

# 语法:lambda 参数列表 : 返回值

# 匿名函数一般都是作为参数使用,其他地方一般不会使用

如:

def fn5(a , b):

​ return a + b

用匿名函数写:

lambda a,b : a + b

用法:

# 1、(lambda a,b : a + b)(10,20)

# 2、fn6 = lambda a,b : a + b

# print(fn6(10,30))

匿名函数的目的是为了简单的写,显然第一种和第二种都和直接写函数差不多了,所以一般都不用。

3、直接作为参数

r = filter(lambda i : i > 5 , l)

# print(list(r))

# 3、map()函数

# map()函数可以对可迭代对象中的所有元素做指定的操作,然后将其添加到一个新的对象中返回

例子:

l = [1,2,3,4,5,6,7]

r = map(lambda i : i + 1 , l)

# print(list(r))

结果:

[2,3,4,5,6,7,8]

# 4、sort()方法

# 该方法用来对列表中的元素进行排序,默认从小到大排

# sort()方法默认是直接比较列表中的元素的大小

例子:

l = ['bb','aaaa','c','ddddddddd','fff']

# l.sort()

这里调用sort()排序是直接比较Unicode编码

如果我们想用它来比较字符串长度然后排序,那么:

# 在sort()可以接收一个关键字参数key,key需要一个函数作为参数,当设置了函数作为参数,每次都会以列表中的一个元素作为参数来调用函数,并且使用函数的返回值来比较元素的大小

例子:

l = ['bb','aaaa','c','ddddddddd','fff']

# l.sort(key=len)

bb调用len后返回值为2,fff调用len后返回值为3,然后比较返回值

l = [2,5,'1',3,'6','4']

l.sort(key=int)

# print(l)

这相当与把它们转为int型后比较

# 5、sorted()函数

# 这个函数和sort()的用法基本一致,但是sorted()可以对任意的序列进行排序

# 并且使用sorted()排序不会影响原来的对象,而是返回一个新对象(列表)

例子:

l = "123765816742634781"

print(sorted(l,key=int))#这里传不传key都可以

标签:return,函数,形参,作用域,参数,print
From: https://www.cnblogs.com/nanguyhz/p/16800084.html

相关文章

  • 函数式编程和Lambda的延迟执行
    函数式编程在兼顾面向对象特性的基础上java语言通过Lambda表达式与方法引用等为开发者打开了函数式编程的大门Lambda的延迟执行有些场景的代码执行后结果不一定会......
  • 函数式接口概念和作用
    函数式接口概念函数式接口在java中是指:有且仅有一个抽象方法的接口函数式接口即适用于函数式编程场景的接口而java中的函数式编程体现实Lambda所以函数式接口就是......
  • 函数式接口-常见函数式接口-Function接口
    常见函数式接口JDK提供了大量常用的函数式接口以丰富Lambda的经典使用常见它们注意在java.util.function包中被提供Function接口Function<T,R>接口用于根据一个类型......
  • 函数式接口-常见函数式接口-Predicate接口
    常见函数式接口JDK提供了大量常用的函数式接口以丰富Lambda的经典使用常见它们注意在java.util.function包中被提供Predicate接口有时候我们需要对某种类型的数据进......
  • 函数式接口-常见函数式接口-Consumer接口
    常见函数式接口JDK提供了大量常用的函数式接口以丰富Lambda的经典使用常见它们注意在java.util.function包中被提供Consumer接口Consumer<T>接口则正好与Supplier接口......
  • 函数式接口-常见函数式接口-Supplier接口
    常见函数式接口JDK提供了大量常用的函数式接口以丰富Lambda的经典使用常见它们注意在java.util.function包中被提供Supplier接口Supplier<T>接口仅包含一个无参的方......
  • js 外部调用 嵌套函数
     在函外部直接调用函数的内部函数是不可以的,因为是向外查找的 所以不能直接内部函数  functionone(){functiontwo(){varb=30;......
  • C语言零基础入门—函数-习题
    C语言零基础入门—函数-习题本节课的任务是:完成5道习题。下边的题目,都需要使用函数的知识来求解(也就是编写自定义函数求解)01-二元一次函数求解求方程​​ax^2+bx+c=......
  • mysql 中使用 CONCAT 函数进行结果拼接时出现乱码问题
    今天在mysql中使用CONCAT()函数进行结果拼接时出现了乱码问题,如下图所示:  后来发现是因为不同类型的字段进行拼接造成的应使用convert()函数进行类型转换,把非字......
  • ctfshow web99(in_array函数漏洞)
    <?phphighlight_file(__FILE__);$allow=array();//设置为数组for($i=36;$i<0x36d;$i++){array_push($allow,rand(1,$i));//向数组里面插入随机数}if(isset......