Python函数

1. 定义函数

函数是带名字的代码块,用于完成具体的工作。
要执行函数定义的特定任务,可调用该函数。

# 定义函数
def greet_user():
    print("Hello!")

# 调用函数    
greet_user()

# Hello!
# 向函数传递参数
def greet_user(username):
    print("Hello, " + username.title() + "!")

greet_user('jesse')

# Hello, Jesse!

2. 传递参数

2.1 位置实参

def describe_pet(animal_type, pet_name):
    print("\nI have a " + animal_type + ".")
    print("My " + animal_type + "'s name is " + pet_name.title() + ".")

describe_pet('hamster', 'harry')

# I have a hamster.
# My hamster's name is Harry.

2.2 可变参数

def make_pizza(*toppings):
    print(toppings)

make_pizza('pepperoni')
make_pizza('mushrooms', 'green peppers', 'extra cheese')

# ('pepperoni',)
# ('mushrooms', 'green peppers', 'extra cheese')

形参名*toppings中的星号让Python创建一个名为toppings的空元组,并将收到的所有值都封装到这个元组中。

def make_pizza(size, *toppings):
    print("\nMaking a " + str(size) + "-inch pizza with the following toppings:")
    for topping in toppings:
        print("- " + topping)

make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

# Making a 16-inch pizza with the following toppings:
# - pepperoni

# Making a 12-inch pizza with the following toppings:
# - mushrooms
# - green peppers
# - extra cheese

将接纳任意数量实参的形参放在最后。Python先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。

2.3 关键字实参

关键字实参是传递给函数的名称-值对。

def describe_pet(animal_type, pet_name):
    print("\nI have a " + animal_type + ".")
    print("My " + animal_type + "'s name is " + pet_name.title() + ".")

describe_pet(pet_name='harry', animal_type='hamster')

# I have a hamster.
# My hamster's name is Harry.

注意:使用关键字实参时,务必准确地指定函数定义中的形参名。

>>> def person(name, age, **kw):
        print('name:', name, 'age:', age, 'other:', kw)

	
>>> person('Michael', 30)
name: Michael age: 30 other: {}
>>> person('Bob', 35, city='Beijing')
name: Bob age: 35 other: {'city': 'Beijing'}
>>> person('Adam', 45, gender='M', job='Engineer')
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}
>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, city=extra['city'], job=extra['job'])
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, **extra)
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}

注意:关键字参数kw获得的字典是extra的一份拷贝,对kw的改动不会影响到函数外的extra

>>> def person(name, age, *, city, job): # 限制关键字参数的名字
        print(name, age, city, job)

	
>>> person('Jack', 24, city='Beijing', job='Engineer')
Jack 24 Beijing Engineer
>>> person('Jack', 24, province='Guangdong', job='Engineer')
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    person('Jack', 24, province='Guangdong', job='Engineer')
TypeError: person() got an unexpected keyword argument 'province'
>>> def person(name, age, *args, city, job): # args是可变参数,city和job是关键字参数
        print(name, age, args, city, job)

	
>>> person('Jack', 24, 'Guangdong', city='Guangzhou', job='Engineer')
Jack 24 ('Guangdong',) Guangzhou Engineer
>>> person('Jack', 24, 'Guangdong', 170, city='Guangzhou', job='Engineer')
Jack 24 ('Guangdong', 170) Guangzhou Engineer
>>> person('Jack', 24, city='Guangzhou', job='Engineer')
Jack 24 () Guangzhou Engineer

2.4 默认值

def describe_pet(pet_name, animal_type='dog'):
    print("\nI have a " + animal_type + ".")
    print("My " + animal_type + "'s name is " + pet_name.title() + ".")

describe_pet(pet_name='willie')
# describe_pet('willie')

# I have a dog.
# My dog's name is Willie.

Python将实参pet_name视为位置实参。
注意:使用默认值时,在形参列表中必须先列出没有默认值的形参,再列出有默认值的形参。这让Python依然能够正确地解读位置实参。

2.4.1 使用默认参数的坑

>>> def add_end(L=[]):
        L.append('END')
        return L

>>> add_end()
['END']
>>> add_end()
['END', 'END']

定义默认参数要牢记一点:默认参数必须指向不变对象!

>>> def add_end(L=None):
        if L is None:
            L = []
        L.append('END')
        return L

>>> add_end()
['END']
>>> add_end()
['END']

2.5 传递列表

def greet_users(names):
    for name in names:
        msg = "Hello, " + name.title() + "!"
        print(msg)

usernames = ['hannah', 'ty', 'margot']
greet_users(usernames)

# Hello, Hannah!
# Hello, Ty!
# Hello, Margot!

向函数传递列表的副本而不是原件,这样函数所做的任何修改都只影响副本,而丝毫不影响原件。

3. 返回值

def get_formatted_name(first_name, last_name):
    full_name = first_name + ' ' + last_name
    return full_name.title()

musician = get_formatted_name('jimi', 'hendrix')
print(musician)

# Jimi Hendrix

函数可返回任何类型的值,包括列表和字典等较复杂的数据结构。

def build_person(first_name, last_name):
    person = {'first':first_name, 'last':last_name}
    return person

musician = build_person('jimi', 'hendrix')
print(musician)

# {'first': 'jimi', 'last': 'hendrix'}
def build_person(first_name, last_name, age=''):
    person = {'first':first_name, 'last':last_name}
    if age:
        person['age'] = age
    return person

musician = build_person('jimi', 'hendrix', age=27)
print(musician)

# {'first': 'jimi', 'last': 'hendrix', 'age': 27}

参考资料:

posted @ 2019-04-06 00:46  gzhjj  阅读(213)  评论(0编辑  收藏  举报