零基础入门python3.7 ——基础知识总结(十二) 函数进级

python中的函数调用时除了对位传参。 关键字传参。 默认参数以外还提供了以下传参方式。

一。可变参数

顾名思义可变参数就是参数的个数是可变的,可以是任意1个或者多个,由于参数的数量不确定所以我们要把实际参数定义为列表或者元组。

def sun(arr):
    add_data = 0
    for i in arr:
        add_data += i
    return add_data

a = sun((1, 2, 3, 4, 5))
print(a)
b = sun([1, 2, 3, 4, 5])
print(b)

c = sun([1, 2, 3])
print(c)
d = sun((1, 2, 3))
print(d)

我们可以发现当在函数调用时传入元素个数不等的列表活着元组时都能得到正确的结果。这就是可变参数的用法。

不仅如此可变参数还有简写方式。 请看示例

def sun(*arr):
    add_data = 0
    for i in arr:
        add_data += i
    return add_data

a = sun(1, 2, 3, 4, 5)
print(a)

c = sun(1, 2, 3)
print(c)

此时我们发现只需要在形式参数的前面加上“*”就可以在函数调用是不必关心传入的是列表还是元组了。还是能正确的得到相应的结果。 这种写法即使不传任何参数代码也不会抛出异常。

def sun(*arr):
    add_data = 0
    for i in arr:
        add_data += i
    return add_data

a = sun()
print(a)

0

在来看一个新的情况。 假如说形式参数前面加了“*”,我在函数调用的时候实际参数和一个列表或者元组。假如直接把这个列表或元组直接传进去会出现怎么结果。

def sun(*arr):
    add_data = 0
    for i in arr:
        add_data += i
    return add_data

a = sun((1, 2, 3, 4))
print(a)

Traceback (most recent call last):
  File "/Users/apple/Documents/重要文件/python3/python21.py", line 7, in 
    a = sun((1, 2, 3, 4))
  File "/Users/apple/Documents/重要文件/python3/python21.py", line 4, in sun
    add_data += i
TypeError: unsupported operand type(s) for +=: 'int' and 'tuple'

很显然这样python无法识别这种调用方式来计算结果。那我能不能逐个传呢?

def sun(*arr):
    add_data = 0
    for i in arr:
        add_data += i
    return add_data

d = (1, 2, 3, 4)
a = sun(d[0], d[1], d[2], d[3])
print(a)

10

事实证明这样是可以的。 但是新的问题随之产生了。假如列表或者元组里的元素有1000个呢。 这样写显然不现实。 所以一种新的写法解决了这一问题。

def sun(*arr):
    add_data = 0
    for i in arr:
        add_data += i
    return add_data

d = (1, 2, 3, 4)
a = sun(*d)
print(a)

10

我们不仅得到了想要的结果。而且只需要在实参i前也加一个“*”就得意解决问题。 这是一种常见的写法。

二。命名关键字参数

对于前面说到的关键字传参。我们在设置关键字参数时没有做任何限制。 也就是想把这个参数设置为关键字传参。在调用的时候设置成关键字传参即可,例如

def person(age, tall, city, name):
    person1 = {
        "name": name,
        "age": age,
        "tall": tall,
        "city": city
    }
    print(person1)
#  设置名字为关键字参数
person(23, 178, "成都", name="雯倾浅忆")

#  设置城市和名字为关键字参数
person(23, 178, city="成都", name="雯倾浅忆")

{'name': '雯倾浅忆', 'age': 23, 'tall': 178, 'city': '成都'}
{'name': '雯倾浅忆', 'age': 23, 'tall': 178, 'city': '成都'}

假如说我们要检查age和tall有没有设置为关键字参数该怎么办呢?需要在函数内部通过kw检查。示例如下。

def person(age, name, **kw):
    if "tall" in kw and "city" in kw:
        person1 = {
            "name": name,
            "age": age,
        }
        print(person1)
#  设置名字为关键字参数
person(23, 178, tall=178, city="成都")

{'name': 178, 'age': 23}

那么很显然如果tall和city中的任何一个不是关键字传参的话是不会成功打印对象的。

def person(age, name, **kw):
    if "tall" in kw and "city" in kw:
        person1 = {
            "name": name,
            "age": age,
        }
        print(person1)
    else:
        print("参数不全  无法打印对象")
#  设置名字为关键字参数
person(23, 178, city="成都")

参数不全  无法打印对象

那么新的问题有产生了上述代码中形式参数**ke到底是个什么东西呢?示例如下

def person(age, name, **kw):
    if "tall" in kw and "city" in kw:
        print(kw)
    else:
        print("参数不全  无法打印对象")
#  设置名字为关键字参数
person(23, 178, tall=178, city="成都")

{'tall': 178, 'city': '成都'}

原来kw代表的是命名关键字组成的字典。知道了这一点就可创建在原始的关于person1的字典了。 示例如下

def person(age, name, **kw):
    if "tall" in kw and "city" in kw:
        person1 = {
            "name": name,
            "age": age,
            "tall": kw['tall'],
            "city": kw['city']
        }
        print(person1)
    else:
        print("参数不全  无法打印对象")
#  设置名字为关键字参数
person(23, 178, tall=178, city="成都")

{'name': 178, 'age': 23, 'tall': 178, 'city': '成都'}

上面的写法有存在一个新的问题。就是我可不可设置多余的关键字参数呢?

def person( name, **kw):
    if "tall" in kw and "city" in kw:
        print(kw)
    else:
        print("参数不全  无法打印对象")
#  设置名字为关键字参数
person("小王", age=23, tall=178, city="成都")

{'age': 23, 'tall': 178, 'city': '成都'}

显然这与我们只需要tall和city为关键字的参数的意愿不符合,也就是说调用者仍可以传入不受限制的关键字参数。此时如果要限制关键字参数的名字,就可以用命名关键字参数,示例如下

def person(age, tall, *, city, name):
    person1 = {
        "name": name,
        "age": age,
        "tall": tall,
        "city": city
    }
    print(person1)

person(23, 178, city="成都", name="雯倾浅忆")

{'name': '雯倾浅忆', 'age': 23, 'tall': 178, 'city': '成都'}

和**ke不同的是命名关键字参数需要用”*“而其后的参数将被视为命名关键字参数。如果不设置会抛出异常

def person(age, tall, *, city, name):
    person1 = {
        "name": name,
        "age": age,
        "tall": tall,
        "city": city
    }
    print(person1)

person(23, 178, "成都", name="雯倾浅忆")

Traceback (most recent call last):
  File "/Users/apple/Documents/重要文件/python3/python21.py", line 10, in 
    person(23, 178, "成都", name="雯倾浅忆")
TypeError: person() takes 2 positional arguments but 3 positional arguments (and 1 keyword-only argument) were given

如果形参中存在一个可变参数。则其后的命名关键字参数不需要符号分隔

def person(age, tall, *arr, city, name):
    person1 = {
        "name": name,
        "age": age,
        "tall": tall,
        "city": city,
    }
    print(person1)
    print(arr)

person(23, 178, [1, 2, 2], city="成都", name="雯倾浅忆")

{'name': '雯倾浅忆', 'age': 23, 'tall': 178, 'city': '成都'}
([1, 2, 2],)

在存在可变参数的情况下。其后面跟随的参数必须视为命名关键字参数。否则会抛出异常

def person(age, tall, *arr, city, name):
    person1 = {
        "name": name,
        "age": age,
        "tall": tall,
        "city": city,
    }
    print(person1)
    print(arr)

person(23, 178, [1, 2, 2], "成都", "雯倾浅忆")

Traceback (most recent call last):
  File "/Users/apple/Documents/重要文件/python3/python21.py", line 11, in 
    person(23, 178, [1, 2, 2], "成都", "雯倾浅忆")
TypeError: person() missing 2 required keyword-only arguments: 'city' and 'name'

命名关键字参数可以设置默认值在调用时可以不必传值

def person(age, tall, *, city="成都", name):
    person1 = {
        "name": name,
        "age": age,
        "tall": tall,
        "city": city
    }
    print(person1)

person(23, 178, name="雯倾浅忆")

{'name': '雯倾浅忆', 'age': 23, 'tall': 178, 'city': '成都'}

三。参数组合

在Python中定义函数,可以用必选参数(位置参数)、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数(位置参数)、默认参数、可变参数、命名关键字参数和关键字参数。

你可能感兴趣的:(python,python)