python王者归来—学习笔记(13)

第十一章 函数(函数定义、函数参数、函数返回值、递归调用、局部变量和全局变量、lambda表达式与fileter()及map()函数、pass)

所谓的函数(function)其实就是一系列指令语句所组成。当一个程序在调用函数时,Python会自动跳到被调用的函数上执行工作,执行完后,会回到原先程序执行位置,然后继续执行下一道指令。前面已经经常使用Python内置的函数了,例如,len( )、add( )、remove( )等。有了这些函数,我们可以随时调用使用,让程序设计变得很简洁。

一、函数定义的语法格式如下:

def 函数名称(参数1, 参数2, ...):
    """ 函数批注(docstring) """
    程序代码区块  #要缩进
    return 返回值1, 返回值2, ...
  • 函数名称 名称必须是唯一的,程序未来可以调用引用。
  • 参数值 这是可有可无的,完全视函数设计需要,可以接收调用函数传来的变量,各参数值之间是用逗号“,”隔开。
  • 函数批注 这是可有可无的,不过如果是参与大型程序设计计划,当负责一个小程序时,建议所设计的函数需要加上批注,除了自己需要也是方便他人阅读。主要是注明此函数的功能,由于可能有多行批注所以可以用3个双引号(或单引号)包夹。许多英文Python资料称此为docstring(document string的缩写)。
  • return [返回值1,返回值2 , … ]不论是return或是右边的返回值皆是可有可无,如果有返回多个数据彼此需以逗号“,”隔开。
def greeting1():
    """ 无参数无返回值的函数 """
    print("python 欢迎你")
    print("祝福学习顺利")

def greeting2(name):
    """ 传递一个参数的函数 """
    print("Hi," + name + " 欢迎来到pyhon世界")

#以下程序代码可称做主程序
greeting1()
greeting2('小明')

二、函数参数。函数允许传递零个参数、一个参数或多个参数。当所设计的函数需要传递多个参数,调用此函数时就需要特别留意传递参数的位置需要正确,最后才可以获得正确的结果。最常见的传递参数是数值或字符串数据,有时也会需要传递列表、元组或字典。所谓的关键词参数(keyword arguments)是指调用函数时,参数是用参数名称=值配对方式呈现。Python允许在调用需传递多个参数的函数时,直接将参数名称=值用配对方式传送,这个时候参数的位置就不重要了。在设计函数时也可以给参数默认值,如果调用的这个函数没有给参数值,函数的默认值将派上用场。特别需留意:函数设计时含有默认值的参数必须放置在参数列的最右边。

def interest(interest_type, subject='敦煌'): #设置默认值的参数必须放在最右边
    """ 显示兴趣和主题函数 """
    print("我的兴趣是 " + interest_type)
    print("在 " + interest_type + " 中,最喜欢的是 " + subject)
    print()


#以下程序代码可称做主程序
interest('旅游')  #只传递一个参数,第二个参数使用默认值
interest('旅游', '大理')        #传递两个参数,参数顺序正确
interest('python', '程序设计')  #传递两个参数,参数顺序弄反了
#传递多个参数时,将参数名称=值用配对方式传递,可以忽略参数顺序
interest(subject='python', interest_type='程序设计')

在调用函数时,也可以将列表(此列表可以是由数值、字符串或字典所组成)当参数传递给函数,然后函数可以遍历列表内容,然后执行更进一步的运作。Python允许在函数内直接修订列表的内容,同时列表经过修正后,主程序的列表也将随之永久性更改结果。当传递列表给函数时,即使函数内的列表与主程序列表是不同的名称,但是函数列表与主程序列表实际指向相同的内存位置,所以在函数更改列表内容时主程序列表内容也随着更改。如果想要继续保留主程序列表内容不变,可以在主程序中通过使用副本传递列表参数: 函数名(name_list[:])。

def show_fruits(fruits):
    """ 显示水果列表元素 """
    print("当前有这些水果:", end="")
    for fruit in fruits:
        print(fruit, end=" ")
    print()

def eat_fruits(fruits):
    fruit = fruits.pop()
    print("吃掉了", fruit)

#以下为主程序
old_fruits=['苹果', '香蕉', '西瓜']
show_fruits(old_fruits)
#即使主程序列表名称和函数内列表参数名称不同,仍会修改主程序列表内容
eat_fruits(old_fruits)
show_fruits(old_fruits)

new_fruits=['梨', '柠檬', '葡萄']
show_fruits(new_fruits)
#使用副本方式传递列表,不会修改主程序列表内容
eat_fruits(new_fruits[:])
show_fruits(new_fruits)

在设计Python的函数时,有时候可能会碰上传递任意数量的参数给函数,此时加上“*”符号的参数代表可以有1到多个参数将传递到这个函数内(可以理解为传递元组参数)。有时会遇上需要同时传递一般参数与任意数量参数给函数,碰上这类状况,任意数量的参数必须放在最右边:

#type为一般参数, toppings为任意数量参数,可以理解为传递列表参数
def make_icecream(type, *toppings):
    #列出制作冰淇淋的配料
    print("这个 ", type, "冰淇淋所加配料如下")
    for topping in toppings:
        print("----", topping)

make_icecream('香草', '草莓酱')
make_icecream('芒果', '草莓酱', '葡萄干', '巧克力')

函数的参数可以是关键词参数,我们也可以设计含任意数量关键词参数的函数,加上"**"符号的参数代表可以接受任意数量的关键词参数(可以理解为传递字典参数):

#players为任意数量关键词参数,可以理解为传递字典参数
def build_dict(name, age, **players): 
    #建立球员字典数据
    info = {}    #建立空字典
    info['name'] = name
    info['age'] = age
    for key, value in players.items():
        info[key] = value
    return info

player_dict = build_dict('james', '32', city = 'cleveland', state = 'ohio')
print(player_dict)

三、函数返回值。函数如果没有return语句或者只有return没有返回值,Python会自动返回None。None在Python中独立成为一个数据类型NoneType,相当于其他语言的null

函数允许返回数值、字符串、列表、字典等,也允许返回多个数据,各个数据间只要以逗号隔开即可:

#返回一个字符串参数
def full_name(first_name, last_name):
    full_name = first_name + last_name
    return full_name

#返回多个数值参数
def mutifunction(x1, x2):
    """ 加减乘除运算 """
    addresult = x1 + x2
    subresult = x1 - x2
    mulresult = x1 * x2
    divresult = x1 / x2
    return addresult, subresult, mulresult, divresult

#以下为主程序
info = full_name('刘', '星')
print(info)

x1 = x2 = 10
add, sub, mul, div = mutifunction(x1, x2)
print("加法结果: ", add)
print("减法结果: ", sub)
print("乘法结果: ", mul)
print("除法结果: ", div)
#返回字典
def build_vip(id, name, tel=''): #如果没有输入电话号码则默认为空
    """建立vip信息"""
    vip_dict = {'ID':id, 'Name':name}
    if tel:
        vip_dict['Tel'] = tel
    return vip_dict

member1 = build_vip('101', 'Nelson')
member2 = build_vip('102', 'Henry', '090046656')
print(member1)
print(member2)

四、递归调用。一个函数可以调用其他函数也可以调用自己,其中调用本身的动作称递归式(recursive)调用。递归函数可以使程序变得很简洁,但是设计这类程序一不小心就很容易掉入无限循环的陷阱,所以使用这类函数时一定要特别小心:

def factorial(n):
    #计算n的阶乘,n必须是正整数
    if n == 1:
        return n
    else:
        return n*(factorial(n-1))

value = 3
print(value, "的阶乘结果是:", factorial(value))
value = 5
print(value, "的阶乘结果是:", factorial(value))

五、局部变量和全局变量。某个变量只有在该函数内使用,影响范围限定在这个函数内,这个变量称局部变量。如果某个变量的影响范围是在整个程序,则这个变量称全局变量。对于全局变量而言,一般是在主程序内建立,程序在执行时,不仅主程序可以引用,所有属于这个程序的函数也可以引用,所以它的影响范围是整个程序。

在程序设计时建议全局变量与函数内的局部变量不要使用相同的名称,因为很容易造成混淆。如果全局变量与函数内的局部变量使用相同的名称,Python会将相同名称的区域与全局变量视为不同的变量,在局部变量所在的函数是使用局部变量内容,其他区域则是使用全局变量的内容。

一般程序设计时有关使用局部变量需注意下列事项,否则程序会有错误产生。● 局部变量内容无法在其他函数引用。● 局部变量内容无法在主程序引用。

def printmsg1():
    #函数本身没有定义变量,打印主程序变量值
    print("printmsg1: ", msg)
    a = 1

def printmsg2():
    #函数本身有定义相同名称变量,打印函数内局部变量值
    msg = "Local Variable"
    print("printmsg2: ", msg)

msg = 'Global Variable'
print("main: ", msg)
printmsg1()
printmsg2()
#print(a)  #主程序无法引用函数内局部变量

六、匿名函数(lambda表达式)。所谓的匿名函数(anonymous function)是指一个没有名称的函数,Python是使用def定义一般函数,匿名函数则是使用lambda来定义,有的人称之为lambda表达式,也可以将匿名函数称lambda函数。通常会将匿名函数与Python的内置函数filter( )、map( )等共同使用,此时匿名函数将只是这些函数的参数。匿名函数最大特色是可以有许多的参数,但是只能有一个表达式,然后可以将表达式执行结果返回: lambda arg1, ..., argn : expression。

#定义含一个参数的lambda函数
square = lambda x : x ** 2

#定义含多个参数的lambda函数
product = lambda x, y : x * y

#调用lambda函数
print(square(10))
print(product(5, 10))

匿名函数一般是用在不需要函数名称的场合,例如,一些高阶函数(higher-order function)的参数可能是函数,这时就很适合使用匿名函数,同时让程序变得更简洁。有一个内置函数filter(),它的语法格式如下:filter(function, iterable) 。 该函数依次对iterable(可重复执行如字符串、列表或元组)中的元素(item)放入function(item)内,然后将function(item)函数执行结果是True的元素(item)组成新的筛选对象(filter object)返回。

#使用传统函数定义方式
def oddfn(x):
    #判断是否为奇数
    return x if x % 2 == 1 else None


mylist = [5, 10, 15, 20, 25, 30]

#传回filter_object
filter_object = filter(oddfn, mylist) 
#输出奇数列表
print([item for item in filter_object])
print(list(filter(oddfn, mylist)))


#直接定义lambda函数,并使用list()函数将filtr函数返回的filter object转成列表
squarelist = list(filter(lambda x : (x % 2 == 1), mylist))
print(squarelist)

有一个内置函数map( ),它的语法格式如下:map(function, iterable) 。该函数依次对iterable可重复执行如字符串、列表或元组)中的元素(item)放入function(item)内,然后将function(item)函数执行结果组成新的筛选对象(filter object)返回。

mylist = [5, 10, 15, 20, 25, 30]

#使用list()函数将map函数返回的filter object转成列表
squarelist = list(map(lambda x : x ** 2, mylist))

print(squarelist)

七、pass。我们在设计大型程序时,可能会先规划各个函数的功能,然后逐一完成各个函数设计,但是在程序完成前我们可以先将尚未完成的函数内容放上pass:

def fun(arg):
    pass

print("列出fun的type类型:", type(fun))
print("列出lambda的type类型:", type(lambda x : x))
print("列出内置函数abs的type类型:", type(abs))

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值