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("
I 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("
Making 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("
I 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("
I 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}
参考资料:
- Python3 教程 | 菜鸟教程
- Python教程 - 廖雪峰的官方网站
- 《Python编程从入门到实践》——【美】Eric Matthes 著