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 "", line 1, in 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
视为位置实参。
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 personmusician = 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 personmusician = build_person('jimi', 'hendrix', age=27)print(musician)# {'first': 'jimi', 'last': 'hendrix', 'age': 27}
参考资料:
- 《Python编程从入门到实践》——【美】Eric Matthes 著