函数的概念
 

函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。

函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做自定义函数

函数的定义

你可以定义一个由自己想要功能的函数,以下是简单的规则:

  • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()
  • 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
  • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
  • 函数内容以冒号 : 起始,并且缩进。
  • return [表达式] 结束函数,选择性地返回一个值给调用方,不带表达式的 return 相当于返回 None。
  • 在return关键字下边写的所有的代码将不会被运行
def hello() :
    print("Hello World!")

hello()
def 函数的名字(参数):
    函数体
def func1(a):
    print("函数被调用"+a)

func1("aa")
def max(a, b):
    if a > b:
        return a
    else:
        return b
 
a = 4
b = 5
print(max(a, b))

函数的参数

形参与实参

形参:形式参数,在函数声明时,我们在括号当中写的参数就叫做形参

实参:实际参数,在函数调用时,我们实际往函数当中传的参数

def max(a, b):  # 形参:在函数声明时,我们在括号当中写的参数就叫做形参
    if a > b:
        return a
    else:
        return b
 
a = 4
b = 5
print(max(a, b)) # 实参:函数调用时,我们实际往函数当中传的参数

位置参数

又叫做必须参数,你必须在函数调用的时候进行参数传递,并且位置是一一对应的

关于位置参数,我们不能少传,也不能多传,位置也必须要一致

def printme( str ):
   "打印任何传入的字符串"
   print (str)
   return
 
# 调用 printme 函数,不加参数会报错
printme()

以上实例输出结果:

Traceback (most recent call last):
  File "test.py", line 10, in <module>
    printme()
TypeError: printme() missing 1 required positional argument: 'str'

默认参数

调用函数时,如果没有传递参数,则会使用默认参数。以下实例中如果没有传入 age 参数,则使用默认值:

注意:如果默认参数和位置参数共存的情况下,默认参数必须写在位置参数的后边,如果参数顺序反过来,会报错。

def printinfo( name, age = 35 ):
   print ("名字: ", name)
   print ("年龄: ", age)
   return
 
#调用printinfo函数
printinfo( age=50, name="runoob" )
print ("------------------------")
printinfo( name="runoob" )
名字:  runoob
年龄:  50
------------------------
名字:  runoob
年龄:  35

关键字参数

关键字参数就是我们在调用函数的时候,把参数的名字同时也写上

特点是:如果我们使用了关键字参数的形式,那么函数参数的位置就可以任意写了

def printme( str ):
   print (str)
   return
 
#调用printme函数
printme( str = "4")
def printinfo( name, age ):
   print ("名字: ", name)
   print ("年龄: ", age)
   return
 
#调用printinfo函数
printinfo( age=50, name="runoob" )
名字:  runoob
年龄:  50

不定长参数

在声明函数时,参数的名字前边要加一个星*

进入到函数内部的时候,函数会将不定长参数解析成为一个元组

def printinfo( arg1, *vartuple ):
   print ("输出: ")
   print (arg1)
   print (vartuple)
 
# 调用printinfo 函数
printinfo( 70, 60, 50 )
70
(60, 50)

如果在函数调用时没有指定参数,它就是一个空元组。我们也可以不向函数传递未命名的变量

def printinfo( arg1, *vartuple ):
   print ("输出: ")
   print (arg1)
   for var in vartuple:
      print (var)
   return
 
# 调用printinfo 函数
printinfo( 10 ) # 10
printinfo( 70, 60, 50 )  # 70 60 50

可变参数

还有一种就是参数带两个星号 **基本语法如下:

在声明函数时,参数的名字前边要加两个星**

调用函数的时候,我们必须以key=value,key=value的形式来进行参数传递

进入到函数内部的时候,函数内部会将所有的参数解析成为一个字典

def printinfo( arg1, **vardict ):
   print ("输出: ")
   print (arg1)
   print (vardict)
 
# 调用printinfo 函数
printinfo(1, a=2,b=3)
1
{'a': 2, 'b': 3}

强制位置参数

Python3.8 新增了一个函数形参语法 / 用来指明函数形参必须使用指定位置参数,不能使用关键字参数的形式。

在以下的例子中,形参 a 和 b 必须使用指定位置参数,c 或 d 可以是位置形参或关键字形参,而 e 和 f 要求为关键字形参:

def f(a, b, /, c, d, *, e, f):
    print(a, b, c, d, e, f)

f(10, 20, 30, d=40, e=50, f=60)

f(10, b=20, c=30, d=40, e=50, f=60)   # b 不能使用关键字参数的形式
f(10, 20, 30, 40, 50, f=60)           # e 必须使用关键字参数的形式

return 语句

return [表达式] 语句用于退出函数,选择性地向调用方返回一个表达式。不带参数值的 return 语句返回 None。

def sum( arg1, arg2 ):
   # 返回2个参数的和."
   total = arg1 + arg2
   print ("函数内 : ", total)
   return total
 
# 调用sum函数
total = sum( 10, 20 )
print ("函数外 : ", total)

def demo(x, y):
    sum = x + y
    print("inside:", sum) # inside: 6

result = demo(1, 5) 
print("outside: ", result)   # outside:  None

函数的多个返回值

当我们一个函数返回多个值的时候,我们用一个参数去接收返回值得时候,那么这个参数就是一个元组,元组中包含了所有函数返回的值

def calc(a,b):
    a += 1
    b += 1
    return a,b

r = calc(1,2)
print(r) # (2, 3)  返回的是一个元组
print(type(r)) # <class 'tuple'>

当然,我们也可以使用多个值去一一对应的接收这些返回值

def calc(a,b):
    a += 1
    b += 1
    return a,b

r1,r2 = calc(3,4)
print(r1,r2) # 4 5

如果我们的函数的返回值是一个元组,它仍然具备多个返回值的特点,也可以使用多个值去接收函数的返回值,这些值必须与返回的值一一对应

def calc(a,b):
    a += 1
    b += 1
    return (a,b)

r = calc(1,2)
print(r) # 返回一个元组 (2, 3)
print(type(r))  # <class 'tuple'>

r1,r2 = calc(5,6)
print(r1,r2) # 6 7

当函数有多个返回值的时候,我们要么用一个值去接收函数的返回值,要么用多个值去接收函数的返回值,这里的多个值必须与函数返回值的数量相同

def calc(a,b):
    a += 1
    b += 1
    return (a,b)

# r1,r2,r3 = calc1(5,6)

def calc1(a,b,c):
    a += 1
    b += 1
    c += 1
    return a,b,c

# r1,r2 = calc1(6,7,8)

当我们在接收返回值的时候,有一些返回值我们不想要了,那么就用下划线_丢弃

def calc1(a,b,c):
    a += 1
    b += 1
    c += 1
    return a,b,c

r1,_,_= calc1(1,2,3)
print(r1) # 2

r1,r2,_ = calc1(3,4,5)
print(r1,r2) # 4 5

_,r1,r2 = calc1(7,8,9)
print(r1,r2) # 9 10

r1,_,r2 = calc1(7,8,9)
print(r1,r2) # 8 10

函数名和系统函数重名

列表list_1的长度是3,而程序结果输出6,并没有正确的输出列表的长度。 说明:len()函数是Python内置函数,可以用于计算列表长度,程序中自定义了len()函数,与内置函数重名,对列表list_1应用len()函数,调用的是自定义函数,没有实现列表长度的计 算。

def len(x): 
    res = 1
    for i in x: 
        res *= i

    return res

list_1 = [1, 2, 3] 
print(len(list_1))

闭包

在一些语言中,在函数中可以(嵌套)定义另一个函数时,如果内部的函数引用了外部的函数的变量,则可能产生闭包。

闭包可以用来在一个函数与一组“私有”变量之间创建关联关系。

在给定函数被多次调用的过程中,这些私有变量能够保持其持久性

嵌套函数,函数内部声明一个函数

def func1():
    print("我是函数1")
    def func2():
        print("我是内部的函数")
    func2()

func1()

私有变量,变量的作用域

a = 1  # 暂时我们可以把a看成是全局变量
def func3():
    print(a)
    b = 2
    print(b) # 函数内可以访问变量 b,但是出了这个函数,就访问不到变量 b 了

func3()
# print(b) # "b" is not defined 外面访问函数里面的变量 b 是访问不到的

一个函数的返回值,也可以是一个函数的引用

def func1():
    print("我是函数1")
    def func2():
        print("我是内部的函数")
        return 1
    return func2

f1 = func1() 
print(f1) # 我是函数1  <function func1.<locals>.func2 at 0x104d2a8e0>
print(type(f1))  #  <class 'function'>
f1()  # 我是内部的函数

如果我们有一个函数,让他可以任意的计算一个值的任意次幂

def exponent(a,b):
    return a ** b

自定义函数,使用闭包实现

def warpper(exponent):
    def exponent_of(base):
        return base ** exponent
    return exponent_of

# 计算一个函数的平方
square = warpper(2)

print(square(2))
print(square(3))
print(square(4))
print(square(5))

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部