05 函数与变量作用域之二


目录

  • 函数

    • 函数基本概念
    • 函数四大参数
  • 变量作用域

    • 全局变量
    • 局部变量

一、函数

(二)函数四大参数

1.必须参数

def add(x,y):    #形式参数:即形参,定义阶段   #如果定义函数时有形参,就必须传递和赋值
  result = x + y
  return result

a = add(1,2)     #实际参数:即实参,调用阶段

2.关键字参数
优势:可以不遵守形参的顺序,可读性好

def add(x,y):    
  result = x + y
  return result

a = add(x = 1,y = 2)    #在调用阶段,明确形参和实参的对应关系
或
a = add(y = 2,x = 1)  

3.默认参数
优势:当有很多参数时,且有重复的,省的一个一个敲

正常情况下:

def print_student_file(name,gender,age,college):
  print('我叫'+name)
  print('我今年'+str(age)+'岁')    #str不能与int相加
  print('我是'+gender+'生')
  print('我在'+college+'上学')

print_student_file('鸡小萌','男',18,'人民路小学')
print_student_file('石敢当','男',18,'人民路小学')
.
.   #50个人,除了名字不同,其他都相同。调用时,其他参数就重复敲50遍

-->
...
...
.
.

用默认参数进行简化:

def print_student_file(name,gender = '男',age = 18,college = '人民路小学'):    
#将默认值,提前赋值给重复的形参
  print('我叫'+name)
  print('我今年'+str(age)+'岁')   
  print('我是'+gender+'生')
  print('我在'+college+'上学')

print_student_file('鸡小萌')   #定义时name无默认值,所以调用时必须赋个值传个参
print('~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
print_student_file('石敢当')
print('~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
print_student_file('喜小乐','女',16)

-->
我叫鸡小萌
我今年18岁    #没有赋值,就使用默认值
我是男生
我在人民路小学上学
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
我叫石敢当
我今年18岁   
我是男生
我在人民路小学上学
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
我叫喜小乐
我今年16岁    #有赋值,优先用赋值
我是女生
我在人民路小学上学

坑:
(1)定义时,必须参数必须全在默认参数前面


def print_student_file(name,gender = '男',age = 18,college = '人民路小学',teacher):  

-->
error❌    #teacher作为必须参数,被放在了默认参数之后

(2)只想更改年龄默认值,函数调用应该怎么写?


def print_student_file(name,gender = '男',age = 18,college = '人民路小学'):    

  print('我叫'+name)
  print('我今年'+str(age)+'岁')   
  print('我是'+gender+'生')
  print('我在'+college+'上学')

print_student_file('果果',17)

-->
error❌   #按照顺序,将实参和形参对应起来。计算机:我以为你这里的17是性别...

改正


def print_student_file(name,gender = '男',age = 18,college = '人民路小学'):    

  print('我叫'+name)
  print('我今年'+str(age)+'岁')   
  print('我是'+gender+'生')
  print('我在'+college+'上学')

print_student_file('果果',age = 17)   #用关键字参数,来明确表示

-->
我叫果果
我今年17岁   
我是男生
我在人民路小学上学

(3)调用时,必须参数也必须全在前面



def print_student_file(name,gender = '男',age = 18,college = '人民路小学'):    

  print('我叫'+name)
  print('我今年'+str(age)+'岁')   
  print('我是'+gender+'生')
  print('我在'+college+'上学')

print_student_file('果果',gender = '女',17,college = '光明小学') 

-->
error❌    调用时,17 是必须参数,被放在了关键字参数之后

4.可变参数

本质:定义函数时,形参是可变的
表示:加个星号*

def demo(*param):   #形参可以是任意多个,所以叫可变参数列表
  print(param)
  print(type(param))

demo(1,2,3,4,5,6) 

-->
(1,2,3,4,5,6)
tuple        #会自动将可变参数列表所对应的实参,组装成一个tuple

当然,如果不喜欢用可变参数列表的形式,也可以实现:

def demo(param):     #必须参数
  print(param)
  print(type(param))

demo((1,2,3,4,5,6))    #这里就要传入一个元组了

-->
(1,2,3,4,5,6)
tuple  

特性

(1)如果想从外部直接传递一个元组或列表,怎么办?

def demo(*param):
  print(param)
  print(type(param))

a = (1,2,3,4,5,6) 
demo(a) 

-->
((1,2,3,4,5,6),)   #二维数组
def demo(*param):
  print(param)
  print(type(param))

a = (1,2,3,4,5,6) 
demo(*a)     #加个星号*:将元组a中的每个元素平铺出来,传递到可变参数的函数中去

-->
(1,2,3,4,5,6) 

(2)可变参数,可以与其他参数相结合

  • 与必须参数:必须参数必须在可变参数的前面

    def demo(para1,*param):
  • 与必须参数、默认参数:

    def demo(para1,param2 = 2,*param):

(3)比较复杂的函数参数列表,其顺序对结果有何影响?

def demo(para1,param2 = 2,*param):
  print(param1)
  print(param2)
  print(param)

demo('a',1,2,3)

-->
'a'
1       #排第二位的都将被计算机视为默认参数    
(2,3)   #可变参数,自动组装成tuple
def demo(para1,*param,param2 = 2):   #试试形参换个顺序
  print(param1)
  print(param)
  print(param2)

demo('a',1,2,3,'param')

-->
'a'        
(1,2,3,'param')     #所以除了必须参数外,都被视为可变参数,放进了元组
2     #第三个形参有默认值兜底了

以上都不是预期效果,那怎么办呢?

def demo(para1,*param,param2 = 2):
  print(param1)
  print(param)
  print(param2)

demo('a',1,2,3,param2 = 'param')    #用关键字参数进行指定

-->
'a'
(1,2,3)
'param'
七月老师:
上述参数之所以复杂,非逻辑思维复杂,而是情况太多、难以记忆。
因此,应该尽量确保函数形参列表的类型简单,不建议涉及这么多形参类型。
别人不好调用,不是优质函数

(4)可变参数的使用场景

绝大多数可变参数是用在for循环中,来遍历可变参数列表中的每个参数,然后拿出来用

其优势是:
简化函数的调用,即以平铺的方式传入参数。否则你要将数字组成元组或列表再传入,麻烦

应用场景:
用python编写一个求平方数的函数?

def squsum(*param):
  sum = 0
  for i in param:
    sum += i * i
  print(sum)

squsum(1,2,3)

-->
14

对比:

def squsum(*param):
  sum = 0
  for i in param:
    sum += i * i
  print(sum)

squsum(*(1,2,3))    #将数字组成元组或列表再传入,麻烦

-->
14

5.关键字可变参数

设计一个函数,其形参列表可以支持任意个数的关键字参数?
例题
(1)输出多个城市的温度?

def city_temp(*param):    #可变参数列表
  print(param)
  print(type(param))

city_temp(bj = '32c',xm = '23c',sh = '31c')   #带关键字的可变参数的列表

-->
error ❌  #一个星号是不能表示带关键字的可变参数的
def city_temp(**param):   #那就再加一个星号
  print(param)
  print(type(param))

city_temp(bj = '32c',xm = '23c',sh = '31c')

-->
{bj : '32c',xm : '23c',sh : '31c'}
dict

(2)如何快速的遍历字典呢?

def city_temp(**param): 
  for c in param:      #这里只有一个c
    print(c)

city_temp(bj = '32c',xm = '23c',sh = '31c')

-->
bj
xm
sh    ❌ #只是遍历出了key
def city_temp(**param): 
  for key:value in param:     #那就加上个value
    print(key,":',value)

city_temp(bj = '32c',xm = '23c',sh = '31c')

-->
b:j
x:m
s:h    ❌  #虽然形式上有了value,但很明显认错人了
def city_temp(**param): 
  for key:value in param.items():     #那再调用下param的内置方法items()
    print(key,":',value)

city_temp(bj = '32c',xm = '23c',sh = '31c')

-->
bj : '32c'
xm : '23c'
sh : '31c'

(3)如何将字典传进来?

def city_temp(**param): 
  for key:value in param.items():  
    print(key,":',value)

a = {bj = '32c',xm = '23c',sh = '31c'}
city_temp(**a)     #调用时,加两个**即可

-->
bj : '32c'
xm : '23c'
sh : '31c'

(4)关键字可变参数列表,可以什么值都不传入吗?
可以。

def city_temp(**param): 
  print(param)

city_temp()    #什么值都不传入

-->
{}    #结果是个空字典
def city_temp(param1,**param): 
  print(param1)
  print(param)

city_temp(1)    #可以只传入必须参数,关键字可变参数不用传

-->
1
{}    #结果是个空字典
可变参数列表与关键字可变参数列表
普通的可变参数列表:既可以零散的传每个元素,也可以直接传元组。
关键字可变参数列表:既可以零散的传每个键值对,也可以直接传字典。
目的只有一个:简化函数的调用

声明:Jerry's Blog|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - 05 函数与变量作用域之二


Follow excellence, and success will chase you.