【python基础知识学习(2)】python的函数

一、函数的定义

1.1函数的格式

定义函数的格式如下:

    def 函数名():
        代码

例如:

    # 定义一个函数,能够完成打印信息的功能
    def printInfo():
        print '------------------------------------'
        print '         人生苦短,我用Python'
        print '------------------------------------'

定义了函数之后,就相当于有了一个具有某些功能的代码,想要让这些代码能够执行,需要调用它。调用函数很简单的,通过 函数名() 即可完成调用。

1.2函数的参数

定义带有参数的函数示例如下:

   def mul2(a, b): 
       c = a*b
       print c
       
   mul2(7, 9) #调用带有参数的函数时,需要在小括号中传递数据

另外,关于函数参数,有两个具体的概念:形参和实参

(1)定义时小括号中的参数,用来接收参数用的,称为 “形参”
(2)调用时小括号中的参数,用来传递给函数用的,称为 “实参”
其中,形参可以分别是缺省参数,不定长参数; 实参可以分为位置参数和关键字参数。

1.实参的位置参数

函数调用时,按形参的位置,从左往右,一一匹配传递参数。位置参数必须一一对应,缺一不可。

   def mul2(a, b): 
       c = a*b
       print c
       
   mul2(7, 9) #7,9这两个实参的传递方法是位置参数

2.实参的关键字参数

函数调用时,通过 形参=值 方式为函数形参传值,不用按照位置为函数形参传值,这种方式叫关键字参数。

   def mul2(a, b): 
       c = a*b
       print c
       
   mul2(b=9, a=7) #7,9这两个实参的传递方法是关键字参数,传入顺序可与形参定义顺序不同

注意:
(1)关键字参数必须在位置参数的右边,且对同一个形参不能重复传值。
(2)如果位置参数和关键字参数同时混合使用,那么顺序上必须先传位置参数,再传关键字参数。

3.形参的缺省参数

形参设定默认值,称为缺省参数,也叫默认参数
元组型不定长参数:形参变量名前面加上一个*,这个参数则为元组型不定长参数。元组型可变形参必须在形参列表的最后边

# *args 不定长参数,可以接收0~多个实参
# 把实参的1,2,3, 包装成元组(1, 2, 3)再传递, 等价于args = (1, 2, 3)
def func(*args):
    # 函数内部使用,无需加*
    print(args, type(args))

# 函数调用
func(1, 2, 3)

-------------------------以下是函数的输入结果----------------------------
(1, 2, 3) <class 'tuple'>

字典型不定长参数:定义参数时需要在形参名前添加**,则为字典型不定长参数。字典型可变形参必须在形参列表的最后边

# 把实参包装成 {'city': 'sz', 'age': 18}给kwargs传递
# kwargs = {'city': 'sz', 'age': 18}
def func(name, **kwargs):
    # 同时存在形参name, name不会被包装到字典中
    print(name)
    print(kwargs)  # 函数内部使用,无需加*

# 实参的写法: 变量=数据,变量=数据
func(name='mike', city='sz', age=18)

-------------------------以下是函数的输入结果----------------------------
mike {'city': 'sz', 'age': 18}

函数参数的关键要点总结:

(1)缺省参数需要在非缺省参数之后 。

(2)关键字参数需要在位置参数之后 。

(3)所有传递的关键字参数必须有对应参数,并且顺序不重要。

(4)参数只能赋值一次。

(5)缺省参数是可选参数,可以不传。

1.3函数的返回值

“返回值”,就是程序中函数完成一件事情后,最后给调用者的结果。想要在函数中把结果返回给调用者,需要在函数中使用return关键字,示例如下:

    def add2num(a, b):
        return a+b

注意,当一个函数返回了一个数据,如果想要用这个数据,那么就需要保存。

保存函数的返回值示例如下:

    #定义函数
    def add2num(a, b):
        return a+b

    #调用函数,顺便保存函数的返回值
    result = add2num(72,17)

    #因为result已经保存了add2num的返回值,所以在接下来的场景中,就可以使用了
    print (result) #结果等于89

在python中,我们可以返回多个值。方法是在关键字return后面将多个返回值用逗号隔开就好。

1.4引用和引用传参

在python中,值是靠引用来传递来的。 我们可以用id()来判断两个变量是否为同一个值的引用。 我们可以将id值理解为变量在计算机中的内存地址标示。如下实例:

a = 1
b = a
id(a)  # 
id(b)  # 输出:13033816, 注意两个变量的id值相同 

a = 2
id(a)   # 输出:13033792, 注意a的id值已经变了
id(b)   # 输出:13033816, b的id值依旧 

下面具体可变数据类型列表的引用:

a = [1, 2]
b = a
id(a) # 输出:139935018544808
id(b) # 输出:139935018544808, 注意两个变量的id值相同 

a.append(3)
print(a)  # 输出:[1, 2, 3]
id(a)  # 输出:139935018544808, 注意a与b始终指向同一个地址 

因此,数据类型可变还是不可变的本质是:在改变数据具体的值时,其内存的id地址索引是否改变;变的话当前数据为不可变数据类型,不变的话则为可变数据类型。

Python中函数参数是引用传递(注意不是值传递)。因此,可变类型与不可变类型的变量分别作为函数参数时,产生的影响是不同的。具体来说,对于不可变类型,因变量不能修改,所以函数中的运算不会影响到变量自身;而对于可变类型来说,函数体中的运算有可能会更改传入的参数变量。示例如下:

a = [1,2,3]
def add(arr):
    arr += arr

add(a)
print(a)

上述代码输出的结果为[1,2,3,1,2,3]。即,传入的实参是可变数据类型列表,且通过函数改变了原本的值。再看下面的不改变原本值的例子:

a = [1,2,3]
def add(arr):
    arr = arr + arr

add(a)
print(a)

上述代码输出的结果为[1,2,3]。即,传入的实参是可变数据类型列表,但是没有通过函数改变了原本的值。主要原因是 ‘=’ 和 ‘+=’ 的区别: ‘=’ 的使用会直接创建一个新的变量,而 ‘+=’ 则是直接对原变量进行操作。

1.5函数的嵌套调用

一个函数里面又调用了另外一个函数,这就是所谓的函数嵌套调用。示例如下:

    def testB():
        print('---- testB start----')
        print('这里是testB函数执行的代码... ')
        print('---- testB end----')


    def testA(): 
        print('---- testA start----') 
        testB()                             #在函数A中,调用函数B
        print('---- testA end----')

    testA()                               #执行函数B

上述代码块的执行结果如下:

    ---- testA start----
    ---- testB start----
    这里是testB函数执行的代码... 
    ---- testB end----
    ---- testA end----

二,函数中的变量

2.1局部变量

(1)局部变量,就是在函数内部定义的变量
(2)不同的函数,可以定义相同的名字的局部变量,而且,这些同名局部变量在各自的函数中使用,相互间不会产生影响或冲突
(3)局部变量的作用是为了实现在函数中临时保存数据需要,而定义的变量。
例如,以下函数中的变量a,b,c就是局部变量。

   def mul2():
       a = 7
       b = 9
       c = a*b
       print c

2.2全局变量

如果一个变量,既能在一个函数中使用,也能在其他的函数中使用,这样的变量就是全局变量。示例如下:

a = 10   #全局变量

def test1():
	a = 30
    print('test1中的变量a的值:', a)
	a = 70
    print('test1中的变量a修改后的值:', a)
    
def test2():
	print('test2中的变量a的值:', a)

如上述代码所示,第一行定义在函数外面的a是一个全局变量。
注意,上述代码出现了全局变量和局部变量名字相同问题,即a在函数test1中是局部变量。
此时,代码的运行结果如下:
在这里插入图片描述

即,如果全局变量的名字和局部变量的名字相同,那么函数中使用的是局部变量的,记忆小技巧:强龙不压地头蛇
此外,既然全局变量能够在所有的函数中进行使用,那么可否进行修改呢?当然可以,我们可以使用关键字global在函数中指定修改全局变量,如下所示:

a = 10   #全局变量

def test1():
	global a
    print('test1中的变量a的值:', a)
	a = 70
    print('test1中的变量a修改后的值:', a)
    
def test2():
	print('test2中的变量a的值:', a)

上述代码的运行结果如下:
在这里插入图片描述

2.3 可变/不可变全局变量

对于不可变的数据类型来说(数字,字符串,元组),如果不使用global,就尝试在函数中修改全局变量会引起报错,如下实例:

a = 1 #定义全局变量
def f():
	a += 1
	print a

f()  #执行函数

-----------------------以下为报错信息-----------------------
在这里插入图片描述
在函数中不使用global声明全局变量时,不能修改全局变量的本质是不能修改全局变量的指向,即不能将全局变量指向新的数据。
对于不可变类型的全局变量来说,因其指向的数据不能修改,所以不使用global时无法修改全局变量。

对于可变类型的全局变量来说(列表,字典,集合),因其指向的数据可以修改,所以不使用global时也可修改全局变量。如下示例:

lst = [1,]
def f2():
	lst.append(7)
	print (lst)

f2()
-----------------------以下为函数f2()执行结果-----------------------
[1, 7] 

三、高级函数用法

3.1递归函数

通过前面的学习知道一个函数可以调用其他函数。 如果一个函数在内部不调用其它的函数,而是调用自己本身的话,这个函数就是递归函数。

举个例子,我们来计算阶乘 n! = 1 * 2 * 3 * … * n
看阶乘的规律:

1! = 1
2! = 2 × 1 = 2 × 1!
3! = 3 × 2 × 1 = 3 × 2!
4! = 4 × 3 × 2 × 1 = 4 × 3!
…
n! = n × (n-1)!

我们可以把阶乘定义为某种函数,让它在执行的时候调用它本身,如下述代码所示:

def cal_factorial(num):
	if num >= 1:
    	result = num * cal_factorial(num-1)
    else:
    	result = 1
    return result

当num=3时,上述代码的执行逻辑如下图所示:
在这里插入图片描述
除了上述完成的递归实现,其实阶乘还可以使用循环来实现,如下代码所示:

def cal_factorial(num):
	i = 1
    result = 1
    
    while i <= num:
    	result *= i
        i += 1
        
    return result

3.2匿名函数

匿名函数是用关键词lambda创建的小型函数。这种函数得名源于定义时,省略了用def声明函数的标准步骤。

lambda函数的语法只包含一个语句,如下

    lambda [arg1 [,arg2,.....argn]]:expression

下面使用匿名函数实现两数相加的操作:

    cal_sum = lambda arg1, arg2: arg1 + arg2

    #调用sum函数
    print("Value of total : ", cal_sum( 10, 20 ) )
    print("Value of total : ", cal_sum( 20, 20 ) )

以上实例输出结果:
在这里插入图片描述
需要注意的是,Lambda函数能接收任何数量的参数但只能返回一个表达式的值。而且,匿名函数不能直接调用print,因为lambda需要一个表达式。

匿名函数大多数的应用场合是作为参数传递,因为其小巧灵活的编写方式。举个例子:

#定义函数
def fun(a, b, opt):  
	print "a =", a
	print "b =", b
	print "result =", opt(a, b)
#执行函数
fun(1, 2, lambda x,y:x+y)  
----------------------------------以下是函数的执行返回结果----------------------------------
a = 1
b = 2
result = 3
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lingchen1906

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值