python 基础知识第10讲:函数的初识、参数、解包

2019-08-23 16:36:01 浏览数 (1)

1.函数

函数也是一个对象,就是我们在内存当中所开辟的一块区域,通过一些代码块实现特定的功能 。 可以用来保存一些可执行的代码,并且可以在需要的时候,对这些代码(语句)进行多次调用。

  • 内置函数
  • 自定义函数

1.1函数的定义

函数名必须按照标识符的命名规范 (可以包含字母 数字 下划线 但是不能以数字开头)

语法: def 函数名([形参1,形参2...]): 代码块

注:函数中保存的代码块不会立即执行,需要调用函数代码才会执行
代码语言:javascript复制
 def fn():
     print('这个是我第一个函数')
     print('哈哈哈')
     print('同学们好')
     print('又到了周末')

print(fn) <function fn at 0x00000000003D1E18> 此时打印出来的是一个函数所在的内存地址 fn是函数对象 fn() 调用函数

1.2函数的调用

函数对象()

2函数的参数

先看一个例子

代码语言:javascript复制
 def fn2(a,b):

     print('a =',a)
      print('b =', b)
     print(a,' ',b,'=',a b)
 fn2(2,3)
 fn2(222,666)

  • 1在定义函数的时候,可以在函数后面的括号定义不等的形参
  • 多个形参我们用 , 隔开
  • 形参(形式参数) 定义形参就相当于在函数内部声明了变量,但是不是赋值
  • 2 实参(实际参数) 指定了形参,那么你在调用函数的时候必须传递实际参数
  • 实际参数将会赋值给对应的形参,就是你有几个形参就需要传递几个实参

2.1函数的参数传递方式

默认值 定义形参的时候,可以给形参指定默认值,指定了默认值之后, 如果用户传递了实参默认值不会发挥任何作用,如果用户没有传递,则默认值会发挥作用

观看以下例子

代码语言:javascript复制
def fn(a,b,c=20):
    print('a = ',a)
    print('b = ',b)
    print('c = ',c)
fn(1,2,3)

输出结果为: a = 1 b = 2 c = 3 此结果符合:如果用户传递了实参默认值不会发挥任何作用 此结论

代码语言:javascript复制
def fn(a,b,c=20):
    print('a = ',a)
    print('b = ',b)
    print('c = ',c)
fn(1,2)

输出结果为: a = 1 b = 2 c = 20 此结果符合:如果用户没有传递,则默认值会发挥作用

2.1.1函数实参的传递方式

  • 位置传递

位置参数就是将对应位置的实参赋值给对应位置的形参. 第一个实参赋值给第一个形参,第二个实参赋值给第二个形参...

  • 关键字参数

关键字参数,可以不按照形参定义的顺序去传递,而根据参数名去传递 如系统内置的一些,print('111',end='')

代码语言:javascript复制
def fn(a = 5,b = 10,c = 20):
     print('a =',a)
     print('b =',b)
     print('c =',c)
fn(b=1,c=2,a=5)
  • 位置参数和关键字参数可以混合使用

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

代码语言:javascript复制
def fn(a = 5,b = 10,c = 20):
     print('a =',a)
     print('b =',b)
     print('c =',c)
fn(1,c=8)

2.1.2函数实参的类型

实参可以传递任意类型的对象 但是如果当一个函数中当出现数据相加,但是传递的参数当中有字符串时,虽然ide不会报错,但是实际函数执行的时候会报错,我们可以通过异常处理机制进行处理

代码语言:javascript复制
 def fn2(a):
   print('a =', a)
# b = 123
# b = 'python'
# b = None
# b = False
# fn2(b)
# fn2(fn)  传递一个函数,指向的是这个函数的内存地址 
  • 我们看下面一个例子
代码语言:javascript复制
def fn4(a):
    a = 20
    a[0] = 50
    print('a =',a,id(a))

c = 10
fn4(c)

执行结果如下: a = 20 1548185664

c= 10 通过上面的结果们可以看出: 在函数中对形参进行重新赋值,不会影响其他的变量

  • 再看一个例子
代码语言:javascript复制
def fn4(a):
    a[0] = 50
    print('a= ',a,id(a))

c = [1,2,3]
fn4(c)
print('c= ',c,id(c))

执行结果为: a= [50, 2, 3] 2591199028936 c= [50, 2, 3] 2591199028936 通过结果我看可以看出此参数c传递后,形参a和c指向的是同一个对象,所以在内部修改相应的元素,c也会变

  • 再看下面的例子
代码语言:javascript复制
def fn4(a):
    a[0] = 50
    print('a= ',a,id(a))

c = [1,2,3]
fn4(c.copy())
print('c= ',c,id(c))

执行结果为: a= [50, 2, 3] 2757291878344 c= [1, 2, 3] 2757289404104 由上面的结果我们可以得出: 如果你在传递的是一个可变对象的时候,而你又不希望我在函数内部的操作影响到函数外部的时候。那么你就可以考虑传递一个对象的副本,通过对象.copy()的方式将其复制一份

2.2函数的不定长参数

其实就是将多余的参数放进一个包里

(*a处理位置参数 **a处理的是关键字参数)

在定义函数时,可以在形参前边加上一个*,这样做的好处是这个形参可以获取到所有的实参. 它将会把所有的实参保存到一个元组当中

先看一段代码:

代码语言:javascript复制
#定义一个函数,求任意个数的和
def sum(a,b,c):
    print(a,b,c)

sum(1,2,3)

此时当我们想传起过3个数的时候,程序会报错,这个时候我们可以使用不定长参数来解决 我们可以将上面的代码改写成下面这样:

代码语言:javascript复制
def sum(*a):
    # 定义一个变量 用来保存的结果
    result = 0
    # 遍历元祖,并将元祖中的数进行计算
    for n in a:
        result = result   n
    print(result)
sum(12,45,46,55,20)

执行结果为:178

===================================================================

不定长参数也可以和其他参数配合使用 不定长参数不是必须写在最后,但是要注意,带*的参数后面的所有参数,必须以关键字的参数形式传递

代码语言:javascript复制
def fn2(*a,b,c):
    print('a =',a)
    print('b =',b)
    print('c =',c)

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

结果为: a = (1, 2, 3) b = 4 c = 5

===================================================================

** 形参可以接受其他的关键字参数,它会将这些参数统一保存到一个字典当中 自定的key就是关键字的名字,字典的value就是参数的值 **形参只能有一个 并且必须写在所有参数后面

代码语言:javascript复制
 def fn3(b,c,**a):
     print('a =', a)
     print('b =', b)
     print('c =', c)
 fn3(b=1,d=2,c=3,e=5,f=20)

执行结果为: a = {'d': 2, 'e': 5, 'f': 20} b = 1 c = 3

2.3函数参数的解包

*param 解包

我们先看一下下面的代码:

代码语言:javascript复制
def fn4(a,b,c):
    print('a =', a)
    print('b =', b)
    print('c =', c)
t=(1,2,3)
fn4(t)

此时执行程序会直接报错

我们把程序稍做调整:

代码语言:javascript复制
def fn4(a,b,c):
    print('a =', a)
    print('b =', b)
    print('c =', c)
t=(1,2,3)
fn4(t[0],t[1],t[2])

上面的方法虽然能解决,但是这只是参数少的情况下,如果我有100个,1000个的时候会写死人的,所以上面的方法并不合适,我们需要把元组赋值给形参

我们根据之前学的方法,可以在序列类型的参数前添加*,这样它会自动将序列当中的元素依次作为参数传递,这里要求序列当中的元素的个数必须和形参的个数保持一致 代码如下:

代码语言:javascript复制
def fn4(a,b,c):
    print('a =', a)
    print('b =', b)
    print('c =', c)
t=(1,2,3)
fn4(*t)

执行结果: a = 1 b = 2 c = 3 上面的这种将序列参数拆开进行传递方式就被称之解包

**param 解包

这种方式用于将字典类型的参数进行解包,因为之前我们在封包的时候通过 param,可以将多余的参数解析为一个字典,但是要注意把字典当参数进行解包时,字典当中的key必须是以关键字的参数传递方式才行

代码语言:javascript复制
def fn4(a,b,c):
    print('a =', a)
    print('b =', b)
    print('c =', c)
t={'a':1,'b':2,'c':3}
fn4(**t)

执行结果: a = 1 b = 2 c = 3

0 人点赞