第八章——函数

145 阅读4分钟

定义函数

函数是带名字的代码块,用于完成具体的工作

#定义函数
#函数是带名字的代码块,用于完成具体的工作
def greet_user(): #向python指出了函数名字
    '''显示简单的问候语'''
    print('Hello!') #函数内部会做的事情
greet_user()

#8.1.1 向函数传递信息
def greet_user(username):
    '''显示简单的问候语。'''
    print(f"Hello,{username.title()}!")
greet_user('jesse')

#8.1.2实参和形参
#在greet_user函数中,username是一个形参,即函数完成工作所需的信息
#在greet_user('jesse')是一个实际参数

#test
def display_message():
    print("one words")
display_message()

def favorite_book(title):
    print(f"the {title} is book")
favorite_book('草上飞')

参数传递

函数定义中可能包含多个形参,因此函数调用中也可能包含多个实参。 多参数的情况下,可以有多种传递方式。1.位置参数,实参的顺序与形参循序相同 2.也可以使用关键字参数 每个实参都由变量名和值组成 3 还可以是列表和字典

#8.2.1 位置参数 最简单的关联方式就是基于实参的顺序
def describe_pet(animal_type,pet_name):
    '''显示宠物的信息'''
    print(f"\n I hava a {animal_type}.")
    print(f"My {animal_type}`s name is {pet_name.title()}.")
describe_pet('hamster','harr`y')

#8.2.2 关键字实参
#关键字实参是传递给函数的名称值对。因为直接在实参中将名称和值关联起来,所以向函数传递实参时不会混淆。
def describe_pet(animal_type,pet_name):
    '''显示宠物的信息'''
    print(f"\n I have a {animal_type}.")
    print(f"My {animal_type}`s name is {pet_name.title()}.")
describe_pet(animal_type='hamster',pet_name='harry') #显示绑定

#8.2.3 默认值
#给定每个形参指定默认值。在调用函数中给形参提供了实参时,python将使用指定的实参值。否则将使用默认值。`
def describe_pet(pet_name,animal_type='dog'):
    '''显示宠物的信息。'''
    print(f"\n I have a {animal_type}.")
    print(f"My {animal_type}`s name is {pet_name.title()}.")
describe_pet(pet_name='wille')
describe_pet('aaa') #按照位置参数绑定 默认第一个

#8.2.4 等效的函数调用
#8.2.5 避免实参错误

#Test
def make_shirt(size=0,words='aaa'):
    print("please input a size and one words!")
    size=int(input("a size="))
    words=input("one words!")
    print(f"\n The size={size} and the words={words}")
make_shirt(words='fff');

返回值

函数并非总是直接显示输出,它可以处理一些数据,并返回一个或一组值

#8.3.1 返回简单值
# def get_formatted_name(first_name,last_name):
#     '''返回整洁的姓名'''
#     full_name=f'{first_name} {last_name}'
#     return full_name.title()
# musician=get_formatted_name('jimi','hendrix')
# print(musician)

#8.3.2 让实参变成可选的
#可以使用默认值来让实参变成可选的
# def get_formatted_name(first_name,middle_name,last_name):
#     '''返回整洁的姓名'''
#     full_name=f"{first_name} {middle_name} {last_name}"
#     return  full_name.title()
# musician=get_formatted_name('john','lee','hooker')
# print(musician)

#给函数默认值  让其变为可选参数
def get_formatted_name(first_name,last_name,middle_name=''):
    '''返回整洁的姓名'''
    if middle_name:  #python 将非空字符串表示为true
        full_name=f"{first_name} {middle_name} {last_name}"
    else:
        full_name=f"{first_name} {last_name}"
    return full_name.title()

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

musician=get_formatted_name('john','hooker','lee')
print(musician)

#8.3.3 返回字典
#函数可以返回任何类型的值,包括列表和字典等较为复杂的数据结构
def build_persion(first_name,last_name):
    '''返回一个字典,其中包含有关一个人的信息'''
    person={'first':first_name,'last':last_name}
    return person
musician=build_persion('jimi','hendrix')
print(musician)

#扩展函数 加入可选参
def build_persion(first_name,last_name,age=None):
    '''返回一个字典,其中包含有关一个人的信息。'''
    person={'first':first_name,'last':last_name}
    if age:
        person['age']=age
    return person
musician=build_persion('jimi','hemdrix',age=27)
print(musician)
musician=build_persion('xxx','aaa')
print(musician)

#8.3.4 结合使用函数和while循环
def get_formatted_name(first_name,last_name):
    '''返回整洁的姓名'''
    full_name=f"{first_name} {last_name}"
    return  full_name.title()
    #这是一个无限循环!
# while True:
#      print("\n please tell me your name:")
#      f_name=input('first name:')
#      l_name=input('last name:')
#
#      formatted_name=get_formatted_name(f_name,l_name)
#      print(f"\n Hello,{formatted_name}!")

#test
def city_country(city_name=None,city_countr=None):
    str=f"{city_name} {city_countr}"
    print(str)
out=city_country('上海')
print(out)
out=city_country( city_countr= 'aaa')
print(out)
out=city_country('aaa','bbb')
print(out)

def make_album(er_name,ed_name):
    '''歌手和专辑字典'''
    if er_name and ed_name:
        sing={'er':{er_name},'ed':{ed_name}}
    print(sing)

make_album('aaa','bbbb')

#增加专辑数
def make_album(er_name,ed_name,count=None):
    if count:
        sign={'er':{er_name},'ed':{ed_name},'count':{count}}
    else:
        sign={'er':{er_name},'ed':{ed_name}}
    print(sign)

make_album('xx','yyy','sadasd')
make_album('ccc','vvvv')

传递列表


def greet_users(names):
    '''向列表中的每位用户发出简单的问候'''
    for name in names:
        msg=f"Hello,{name.title()}!"
        print(msg)

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

#8.4.1 在函数中修改列表
#将列表传递给函数后,函数就可对齐进行修改。而且时永久性的修改
unprinted_designs=['phone case','robot pendant','dodecahedron']
completed_models=[]
while unprinted_designs:
    current_design=unprinted_designs.pop()
    print(f"printing model:{current_design}")
    completed_models.append(current_design)

print("\n The following models have been printed:")
for completed_model in completed_models:
    print(completed_model)

def print_models(unprinted_designs,completed_models):
    while unprinted_designs:
        current_design=unprinted_designs.pop()
        print(f"print model:{current_design}")
        completed_models.append(current_design)
def show_completed_models(completed_models):
    print("\n The following models have been printed:")
    for completed_model in completed_models:
        print(completed_model)

unprinted_designs=['phone case','robot pendant','dodecahedron']
completed_models=[]

print_models(unprinted_designs,completed_models)
show_completed_models(completed_models)

#8.4.2 禁止函数修改列表
print_models(unprinted_designs[:],completed_models)
print(completed_models)

#test
messages=['hello','aaa','what it is?','so how about it ?']
def show_message(messages):
    for mes in messages:
        print(mes)
show_message(messages)

sent_message=[]
def send_messages(mess,sent_mess):
    while mess:
        tmpmes=mess.pop()
        tmp_sent_mess=sent_mess.append(tmpmes)
    print(f"the msee = {sent_mess}")

send_messages(messages,sent_message)

print("传递副本")

传递任意数量实参数

python允许函数从调用语句中收集任意数量的实参

def make_pizza(*toppings):
    '''打印顾客点的所有配料。'''
    print(toppings)

make_pizza('pepperoni')
make_pizza('mushrooms','green peppers','extra cheese')
# 形参*toppings中的星号让python创建一个名为toppings的空元组,并将收到的所有值都分装到这个元组中。

def make_pizza(*toppings):
    print("\n making a pizza with the following toppings:")
    for topping in toppings:
        print(f"-{topping}")

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

#8.5.1 结合使用位置实参和任意数量参数
#如果要让函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后。
def make_pizza(size,*toppings):
    print(f"\n making a {size}--inch pizza with the following toppings?")
    for topping in toppings:
        print(f"-{topping}")

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

#8.5.2 使用任意数量的关键字实参
#将函数编写成能够接受任意数量的键值对,调用语句提供了多少就接受多少。
def build_profile(first,last,**user_info):
    user_info['first_name']=first
    user_info['last_name']=last
    return user_info
user_profile=build_profile('albert','einstein',location='princeton',field='physics')
print(user_profile)

#test
def swindwitch(*pr):
    print(pr)
swindwitch('aaa','bbb','ccc')
swindwitch('111','sss')
gg={'aaa':'aaa'}
swindwitch(gg)

def user_profile(**kwargs):
    first=kwargs.get('first')
    print(first,"lllll")
    last=kwargs.get('last')
    print(last)
    mess=kwargs.get('mess')
    print(mess)
    ans=build_profile(first,last,mess)
    print(ans)


mess={'aaa':'aa','bbb':'bbb'}
ll={'first':'r','last':'hp','mess':mess}
user_profile(ll,mess,mess)