文章目录

  • 形参和实参
  • 位置参数
  • 默认参数
  • 特点
  • 默认参数必须指向不变对象
  • 关键参数
  • 非固定参数 `*args` ` **kwargs`
  • *args
  • **kwargs
  • 特点
  • 限制命名关键字参数


形参和实参

形参只有在调用时才分配内存,调用结束时即刻释放所分配的内存单元,因此形参只在函数内部有效。
实参可以是常量,变量,表达式,函数等,必须有确定的值。

位置参数

调用函数时,依照位次赋值。

def func(x, y):  # 函数名小写(比较规范)形参
    print(x**y)


func(1, 2)  # 1
func(2, 1)  # 2

默认参数

特点

函数调用时,传入参数的值比较固定可以设置成默认参数。




def func(x, y=2):
    print(x**y)


func(2)  # 4
func(2, 3)  # 8

默认参数必须指向不变对象

def func(l=[]):
    l.append('小明')
    print(l)

func([1,2,3,4])
# [1, 2, 3, 4, '小明']

func([1,2])
# [1, 2, '小明']

func()
# ['小明']
func()
# ['小明', '小明']
func()
# ['小明', '小明', '小明']

函数在定义的时候,默认参数L也是一个变量,l默认指向空列表[ ],此时空列表是没有元素的。调用参数赋值时,l指向了其他的列表,函数调用正常。如果没有赋值,l一直指向空列表[ ],空列表作为容器,调用一次增加一个元素,不再是函数定义时的[ ]列表了。

def func(l=None):
    l=[]
    l.append('小明')
    # return l # 返回结果,不打印
    print(l)
func()
func()
# ['小明']
# ['小明']

关键参数

函数调用传入参数值要按顺序,如果不按照顺序,传参时可以使用关键参数。


def register(name, age, city):
    print("""
    name: %s
    age: %s
    city: %s
    """ % (name, age, city))


register('小明',22,'北京')
register('小明',city='北京',age=22)  # 关键参数放在位置参数之后
register(city='北京','小明',age=22)  # 报错

关键字参数最大的优点在于,可以指定默认值,给参数指定默认值后,调用函数时可不提供它!可以根据需要,一个参数值也不提供、提供部分参数值或提供全部参数值。

def hello(name='小明', city='北京'):
    print('欢迎来自{}的{}'.format(city, name))


hello()
# 不提供
# 欢迎来自北京的小明 

hello('小强')
# 按顺序提供部分或全部
# 欢迎来自北京的小强

hello('济南')
# 不按顺序提供需要使用关键字参数
# 欢迎来自北京的济南

hello(city='济南')
# 欢迎来自济南的小明

hello(city='上海',name='小红')
# 欢迎来自上海的小红

非固定参数 *args **kwargs

在不确定传入多少参数时,可以在定义函数时,形参设置为非固定参数。

*args




def re(name, *args):
    print('姓名:', name)
    print('其他信息:', args)


re('小明', 22, '北京')

# 姓名: 小明
# 其他信息: (22, '北京')
def su(*args):
    print(args)
    print(sum(args))

num=[1,2,3]

# su(num) 
# args把num又变成元祖形式([1, 2, 3],)报错,

# 如果传入值是列表形式加*号
su(*num) 

# (1, 2, 3)
# 6
def hello(name, *n, city):
    print('hello', name, 'from', city, n)


# hello('xiaoming', 181,54,'shanghai')报错
hello('xiaoming', 181, 54, city='shanghai')
# hello xiaoming from shanghai (181, 54)


# 有个细小的差别
def hello(name, *n, city):
    print('hello', name, 'from', city, *n)
# hello xiaoming from shanghai 181 54

**kwargs

特点




def re(name, *args, **kwargs):
    print('姓名:', name)
    print('其他信息:', args)
    print('其他信息:', kwargs)


re('小明', 22, '北京', school='北大')

# 姓名: 小明
# 其他信息: (22, '北京')
# 其他信息: {'school': '北大'}
re('小明', 22, '北京', {'school':'北大'})  # 不加**号

# 姓名: 小明
# 其他信息: (22, '北京', {'school': '北大'}) # 元祖
# 其他信息: {}

re('小明', 22, '北京', **{'school':'北大'}) # 加**号
# 姓名: 小明
# 其他信息: (22, '北京')
# 其他信息: {'school': '北大'}

限制命名关键字参数

限制命名关键字参数,调用函数时,必须传入函数要求的关键字参数。




def re(name, *,age,city):  # 限制必须而且只能传入 age=,city=
    print('姓名:', name)
    print('其他信息:', age,city)

# re('小明',age=22,city='北京',school='北大')  # 报错

re('小明',age=22,city='北京')
# 姓名: 小明
# 其他信息: 22 北京

# re('小明',age=22)
# re() missing 1 required keyword-only argument: 'city'
def re(name, *args,age,city):  # 限制必须且只能传入age=,city=
    print('姓名:', name)
    print('其他信息:', args)
    print('限制多余信息:',age,city)

re('小明','180cm',age=22,city='北京')

# 姓名: 小明
# 其他信息: ('180cm',)
# 限制多余信息: 22 北京