Python 3 入门手札(11)函式 Function

使用变量的理由是为了要重复使用同一份数据,同样的,使用函式(Function)的理由是为了要重复使用一段程序。我们可以将需要重复使用的程序片段赋予一个函式名称,然后像变量一样,呼叫这个函式名称来重复使用这个程序片段。

设计自己的函式

定义函式要使用 def,语法如下:

def 函式名称(参数1, 参数2, …):
     程序区块

函式名称的命名规则就跟变量一样,其中参数可以有多个,也可以无参数。如果没有参数,仍须保留小括号。

Python 在执行程序时,会依顺序先看到程序中 def 所定义的函式,它会将内缩的程序区块储存在内存中、用函式名绑定,然后继续往下执行,直到主程序呼叫函式时才会真正的执行函式。呼叫函式必须在函式名称后面加上小括号 (),用于区分是函式名称或是一般变量。

自定义函式跟变量一样,必须先定义然后才能呼叫使用,否则会出现〝NameError: name ‘xxx’ is not
defined〞的错误。

位置参数法与指名参数法

Python 的函数定义很简单,但是在呼叫时的参数传递就有两种。

传递参数值,一般是依照参数定义的顺序来传递,这种依照位置顺序摆放参数值的方式称为〝位置参数法〞(positional parameters)。

不过我们也可以直接用参数的名称来指定参数值,这样就不用依顺序,此方式称为〝指名参数〞(named parameters)或〝关键词参数法〞(keyword parameters)。

我们可以把位置参数和指名参数混着用,但这时位置参数必须在指名参数的前面,这样 Python 才有办法计算位置。

指定参数的默认值

在定义函式时,可以用「参数 = 默认值」的方式来指定参数的默认值,这样在呼叫函式时若省略该参数,参数就会使用默认值。

def calc(w, h, d=1):
    return w * h * d
    
print(calc(3, 4))    # 等于 calc(3, 4, 1)

有默认值的参数必须定义在最后,这样才不会影响到其他参数的位置。另外,如果有多个默认值参数,而我们只想指定较后面的预设参数值时,则可以用指名参数法来指定,例如:

def say_hi(name, title='先生', hi='你好'):
    print(name + title, hi)

say_hi('王小明', hi='好久不见')

使用 return 来传回对象

在函式中可以用 return xxx 来结束函式并传回 xxx 对象,若 xxx 省略则传回 None。

函式和变量、容器一样都是对象

在 Python 中,所有东西都是对象,不只各种数据是对象,连函式也不例外。例如底下的 calc() 函式,我们可以用另一个名称 a 把它绑到 calc() 上:

def calc(w, h):
    return w *h

a = calc
print(a(2, 3))   # 用 a() 一样可以呼叫 clac()

把函式当成参数来传递

既然函式也是对象,自然也可以当成参数来传递(或是当成传回值),例如在底下的 calcAll(容器_A, 函式_B) 函式中,可走访容器_A,并一一呼叫函式_B来取得每个元素的面积:

s = [(3, 4), (2, 4), (5, 3)]

def calc(w, h):
    return w*h

def calcAll(conta, func):
    for r in conta:
        print(func(r[0], r[1]),  end=' ')

calcAll(s, calc)

用 *args 接收不定数目的位置参数

在定义函式时,可以用「*args」来接收不定数目的位置参数,其中 arg 代表 argument,加 s 表示多数(虽然也可以用别的参数名,但习惯上我们都用 args 这个参数名),在函式被呼叫时,所有从 *args 位置(含)开始所对应的参数会被打包成 tuple 指定给 args 参数。

def prn_sum(name, *args):
    print(name, args, '=', sum(args))

prn_sum('加总', 1, 2, 3, 4)       # 1 2 3 4 先打包成 tuple, (1, 2, 3, 4)

在呼叫函式时,所有定义在「*参数」前面的参数都不可省略,而定义在「*参数」后面的参数则只能是〝指名参数〞或〝**kwargs〞。

def prn_sum(name, pre='>', *args, post='#'):
    print(name, pre, args, '=', sum(args), post)

prn_sum('加总', ':', 1, 2, 3, 4, post='元')

以上 name, pre 两个参数不可省略,即使 pre 有默认值也不能省略,而 post 则要以关键词指定,也可以省略,因为有默认值。

使用 **kwargs 来接收不定数目的指名参数

除了用「*args」接收不定数目的位置参数之外,还可用「**kwargs」来接收不定数目的指名参数,在呼叫时对应的参数会被打包成 dict 再指定给 kwargs。也可以用其他的参数名称,但习惯上会使用 kwargs。
在这里插入图片描述
如果同时使用位置参数:*args 及 **kwargs,则必须符合这个顺序:位置参数、*args、**kwargs。

在呼叫函式时,可用 *、**将容器解包

「*容器」会解包成「元素1, 元素2, 元素3, … 」

「**字典」会解包成「键1=值1, 键2=值2, 键3=值3, … 」
在这里插入图片描述

lambda 匿名函式

函式如果很简短,只需要参数列和传回值,那么就可以简写成一个
lambda 表达式,语法如下:

Lambda 参数1, 参数2, … : 传回值

在传回值中可使用前面的各参数来做运算,例如:

Lambda w, h : w*h

如同:

def calc(w, h):
    return w*h

lambda 表达式会产生一个函式对象,就跟一般的函式对象相同,因此很适合用在需要以函式对象为参数的场合。例如:

s = [(3, 4), (2, 4), (5, 3)]

def calcAll(conta, func):
    for r in conta:
        print(func(r[0], r[1]), end=' ')

calcAll(s, lambda w, h : w*h)

lambda 表达式由于不需要替函式取名,因此也称为〝匿名函式〞。不过在必要时还是可以给它绑定一个名字,例如:

calc = lambda w, h : w*h
print(calc(3, 4))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值