自定义函数

35次阅读

共计 4133 个字符,预计需要花费 11 分钟才能阅读完成。

1.1 使用函数
在 Python 中,函数必须先声明,然后才能调用它,使用函数时,只要按照函数定义的形式,向函数传递必需的参数,就可以调用函数完成相应的功能或者获得函数返回的处理结果。
如果函数有返回值,那么需要在函数中使用 return 语句返回计算结果,声明函数的一般形式如下。

1.1.1 声明函数并调用
def < 函数名 > (参数列表):< 函数语句 > return < 返回值 > 其中参数列表和返回值不是必须的,return 后也可以不跟返回值,甚至连 return 也没有。对于 return 后没有返回值的和没有 return 语句的函数都会返回 None 值。有些函数可能既不需要传递参数,也没有返回值。
def tpl_sum(T):
result = 0
for i in T:
result += i
return result

1.2 深入函数
1.2.1 默认值参数
声明一个参数具有默认值的函数形式如下。
def < 函数名 > (参数 = 默认值):< 语句 >
声明了一个带默认值参数的函数,代码如下:
def hello (name=’Python’):
print (‘ 你好,%s!’ % name)
print (‘ 无参数调用时的输出:’)
hello()
print (‘ 有参数 (“Jonson”) 调用时的输出:’)
hello(‘Jonson’)

1.2.2 参数传递
调用函数提供参数时,按顺序传递的参数要位于关键字参数之前,而且不能有重复的情况。
1.2.3 可变数量的参数传递
在自定义函数时,如果参数名前加上一个星号“*”,则表示该参数就是一个可变长参数。在调用该函数时,如果依次序将所有的其他变量都赋予值之后,剩下的参数将会收集在一个元组中,元组的名称就是前面带星号的参数名。
def change_para_num (*tp1):
print (type (tp1)) #输出 tp1 变量的类型
print (tp1)

change_para_num (1)
change_para_num (1,2,3)

当自定义函数时,参数中含有前面所介绍的三种类型的参数,则一般来说带星号的参数应放在最后。当带星号的参数放在最前面时,仍然可以正常工作,但调用时后面的参数必须以关键字参数方式提供,否则因其后的位置参数无法获取值而引发错误。
def change_para_num(*tpl,a,b=0,,**dict):
print(‘tp1:’,tp1)
print(“dict”,dict)
print(‘a:’,a)
print (‘b:’,b)

change_para_num (1,2,3,a=5,c=1,d=2,e=3) #c d e 会以字典的形式储存
change_para_num(1,2,3) #该调用会出错,a 变量没有默认值,也不能获取值

如果要收集不定数量的关键字参数可以在自定义函数时的参数前加两颗星即 **valuename,可以以字典的方式被收集到变量 valuename 之中。
def cube (name, **nature):
all_nature = {‘x’:1,
‘y’:1,
‘z’:1,
‘color’:’white’,
‘weight’:1}
all_nature.update (nature)
print (name,” 立方体的属性:”)
print (‘ 体积:’,all_nature [‘x’]*all_nature [‘y’]*all_nature [‘z’])
print (‘ 颜色:’,all_nature [‘color’])
print (‘ 重量:’,all_nature [‘weight’])

cube (‘first’) #只给出必要参数的调用
cube (‘second’,y=3, color=’red’) #提供部分可选参数
cube (‘third’, z=2, color=’green’, weight=10) #提供部分可选参数

1.2.4 拆解序列的函数调用
前面使用函数调用时提供的参数都是位置参数和关键字参数,实际上调用函数时还可以把元组和字典进行拆解调用。

拆解元组提供位置参数;
拆解字典提供关键字参数。

调用时使用拆解元组的方法是在调用时提供的参数前加一个 * 号;要拆解字典必须在提供的调用参数前加两个 * 号。
def mysum (a,b):
return a+b

print (‘ 拆解元组调用:’)
print (mysum(* (3,4))) #调用时拆解元组作为位置参数
print (‘ 拆解字典调用:’)
print (mysum(**{‘a’:3, ‘b’:4}) #调用时拆解字典作为关键字参数

1.2.5 函数调用时参数的传递方法
Python 中的元素有可变和不可变之分,如整数、浮点数、字符串、元组等都属于不可变的;而列表和字典都属于可变的。
列表和字典的可变也是很好理解的,即它们可以增减元素、修改元素的值。那么整数、浮点数、字符串等为什么是不可变的呢?“=”号的作用是将对象引用与内存中某对象进行绑定,既然整数是不可变的,那么怎么改变一个指向整数的变量的值的呢?答案是直接在内存中创建一个新的整数值,然后将变量引用与其绑定,这虽然本质上的其他高级语言不同,但在使用上是看不出什么差别的,但若将其提供给函数作为参数,则效果不同。
在函数调用时,若提供的是不可变参数,那么在函数内部对其修改时,在函数外部其值是不变的;若提供是可变参数,则在函数内部对它修改时,在函数外部其值也会改变的。
def change (aint, alst): #定义函数
aint = 0 #修改 aint 值
alst[0]=0 #修改 alst 第 1 个值为 0
alst.append (4) #在 alst 中添加一个元素 4
print (‘ 函数中 aint:’, aint) #输出函数中的 aint 的值
print (‘ 函数中 alst:’, alst) #输出函数中的 alst 的值

aint = 3
alst = [1,2,3]
print (‘ 调用前 aint:’, aint)
print (‘ 调用前 alst:’, alst)
change(aint, alst)
print (‘ 调用后 aint:’, aint) #调用后值和调用前值相同
print (‘ 调用后 alst:’, alst) #调用后值和调用前值不同

def myfun (lst= []): #定义有一个默认值为空列表的参数
lst.append(‘abc’)
print (lst)
#此后三次调用自定义函数
myfun()
myfun()
myfun()
#每次调用函数按默认值的理解,应该每次传入空列表,列表中只有一个元素 ’abc’
#在该函数的域上 lst 是已经存在的,在一个线程内多次执行会保留上一次执行的值。

def myfun (lst=None): #定义有一个默认值为空列表的参数
lst = [] if lst is None else lst
lst.append(‘abc’)
print (lst)

myfun()
myfun()
myfun()
#增加一条推导语句,将 lst 置空,就可以达到想要的效果。

1.3 变量的作用域

内置作用域:Python 预先定义的;
全局作用域:所编写的整个程序;
局部作用域:某个函数内部范围。

每次执行函数,都会创建一个新的命名空间,这个新的命名空间就是局部作用域,同一函数不同时间运行,其作用域是独立的,不同的函数也可以具有相同的参数名,其作用域也是独立的。在函数内已经声明的变量名,在函数以外依然可以使用。并且在程序运行的过程中,其值并不相互影响。
def myfun():
a = 0 #函数内声明并初始化变量 a 为整数,局部作用域
a += 3 #修改 a 的值
print (‘ 函数内 a:’, a) #输出函数内 a 的值

a = ‘external’ #全局作用域内 a 声明并初始化

print (‘ 全局作用域 a:’, a)
myfun() #调用函数 myfun()
print(‘ 全局作用域 a:’, a)

# 总结:函数内部声明的 a 和外部声明的 a 在各自的域上互不干扰!

# 那么如何在函数内使用全局作用域的变量呢?
def myfun():
global a #增加此语句
a = 0
a += 3
print (‘ 函数内 a:’, a)

a = ‘external’
print (‘ 全局作用域 a:’,a)
myfun()
print (‘ 全局作用域 a:’, a)

在局部作用域内可以引用全局作用域内的变量,但不可以修改它。
比如以下代码是没有错误的:

a = 3 #定义全局变量 def myprint(): #声明函数 myprint() print (a) #引用全局变量
运行函数 myprint()时,会输出全局变量 a 的值 3。但是若将其改为则会引发错误:

a = 3 #定义全局变量 def myprint(): #声明函数 myprint() print (a) #引用全局变量 a = 5
以上代码引发的错误是局部变量在分配前不能引用,原因是与 Python 中的变量查找有关,在此外代码中函数内声明了 a 变量并初始化,所以 a 被判为局部变量,但却之前在 print(a)中引用了它。
Python 中的变量查找:

1.4 使用匿名函数(lambda)
语法形式如下:
lambda params:expr

其中 params 相当于声明函数时的参数列表中用逗号分隔的参数,expr 是函数要返回值的表达式,而表达式中不能包含其他语句,也可以返回元组(要用括号),还允许在表达式中调用其他函数。
lambda 的示例代码:
import math
s = lambda x1, y1, x2, y2:math. sqrt((x1-x2) **2+(y1-y2) **2)
s(1,1,0,0)
#结果:1.4142135623730951

代码的第二行定义了一个求两坐标点距离的匿名函数,并用 s 引用,之后调用它来求(1,1)与(0,0)坐标点的距离,结果为 1.414。
lambda 一般用来定义以下类型的函数:

简单匿名函数 写起来快速而简单,省代码;
不复用的函数 在有些时候需要一个抽象简单的功能,又不想单独定义一个函数;
为了代码清晰 有些地方使用它,代码更清晰易懂。
比如在某个函数中需要一个重复使用的表达式,就可以使用 lambda 来定义一个匿名函数,多次调用时,就可以少写代码,但条理清晰。

1.5Python 常用内建函数
1.6 定义和使用类
1.6.1 定义类
1.6.2 使用类
1.7 类的属性和方法

正文完
 0