Python3的函数的详解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34195441/article/details/87943419

 

1、函数的定义及调用  y=f(x)

函数是一段代码的表示

def <函数名>(<参数(0个或多个)>)
    <函数体>
    return <返回值>

库函数:input、print、type等

计算n!

def fact(n):
    s = 1
    for i in range(1,n+1):
        s *=i
    return s

a = fact(6)
print(a)

-函数定义时,所指定的参数是一种占位符

-函数定义后,如果不经过调用,不会被执行

-函数定义时,参数是输入、函数体是处理、结果是输出(IPO)

2、函数的参数传递

形参:形式参数,写在函数定义处的参数。

实参:实际参数,写在函数调用处的参数。

位置参数:函数定义时没有默认值的参数,也叫必传参数;调用时的实参必须与形参一一对应。

默认参数:函数定义时有默认值的参数,调用时可以不传递参数;默认参数必须写在最后。

关键字参数:在函数调用时指定参数的名字,参数的位置就无所谓了。

可变长度参数

# 默认值参数必须写在最后面
def show(a, b=5):
    print('a:', a)
    print('b:', b)


# 指定名字后,参数的顺序就无所谓了
# show(b=3, a=2)

# 可变长度参数
def var_len_args(a, b, *arg, **kwarg):
    print(a, b)
    # 是一个元组,存放多传的位置参数
    print(arg)
    # 是一个字典,存放多传的关键字参数
    print(kwarg)

var_len_args(1, 2, 3, 4,5,6, name='二狗', age=18)

# *的使用
def test(a, b):
    print(a, b)


lt = [1, 2]
# 可以这样使用,但是参数多的时候有点不太好用
# test(lt[0], lt[1])
# *可以将一个序列中的元素展开,以上式等价
test(*lt)


def test2(aa, bb):
    print(aa, bb)


d = {'aa': 250, 'bb': 200}
# test2(aa=d['aa'], bb=d['bb'])    #设置的形参要与字典中的键保持一致!!!
# **可以将字典中的键值对展开,作为关键字参数,以上式等价
test2(**d)

运行结果:
1 2
(3, 4, 5, 6)
{'name': '二狗', 'age': 18}
1 2
250 200

(1)参数个数

函数可以有参数,也可以没有,但必须保留括号

def <函数名>():
    <函数体>
    return <返回值>

def fact():
    print("我也是函数")

(2)可选参数传递

函数定义时可以为某些参数指定默认值,构成可选参数

def <函数名>(<非可选参数>,<可选参数>):
    <函数体>
    return <返回值>

def fact(n,m=1):
    s = 1
    for i in range(1,n+1):
        s *= i
    return s//m

>>>fact(10)

 3628800
>>>fact(10,5)
725760

函数定义时可以设计可变数量参数,既不确定参数总数量

def <函数名>(<参数>,*b):
    <函数体>
    return <返回值>


def fact(n,*b):
    s =1
    for i in range(1,n+1):
        s *= i
    for item in b:
        s *= item
    return s

>>>fact(10,3)
10886400
>>>fact(10,3,5,8)
435456000

(3)参数传递的两种方式

函数调用时,参数可以按照位置或名称方式传递

def fact(n,m=1):
    s = 1
    for i in range(1,n+1):
        s *= i
    return s//m


>>>fact(10,5)   #位置传递
725760
>>>fact(m=5,n=10)   #名称传递
725760

3、函数的返回值

(1)函数可以返回0个或多个结果

-return保留字用来传递返回值,可以传递任意多个或0个

-函数可以有返回值,也可以没有,可以有  return  ,也可以没有

# 无参无返回值
def print_ten_hello():
    for i in range(10):
        print('Hello world!')

# print_ten_hello()

# 带参无返回值,可以指定默认值
def print_n_hello(n=10):
	for i in range(n):
      	print('Hello world!')
        
        
# print_n_hello()

# 带参有返回值
def add(a, b):
	ret = a + b
  	# 函数返回值,没有返回值的函数默认返回None
  	return ret  
	# 执行return函数立即结束并返回,后面的代码不会执行
	a += 1

ret = add(3, 5)
print(ret)

# 没有返回,默认返回None
print(print_ten_hello())

运行结果:
8
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
None

(2)函数调用时,参数可以按照位置或名称方式传递

def fact(n,m=1):
    s = 1
    for i in range(1,n+1):
        s *= i
    return s//m,n,m

>>>fact(10,5)   
(725760,10,5)   #元组类型

>>>a,b,c = fact(10,5)
>>>print(a,b,c)
725760  10  5

函数进阶

函数的定义位置是随意的吗?

不是,一定要先定义再调用,也就是说调用一定要放在定义之后

函数的名字是否可以相同?

不可以,虽然语法不报错,但是后者会覆盖前者

函数中能否再定义一个函数?

可以,函数内部定义的函数称为内部函数,它是很多高级功能的基础

4、局部变量和全局变量

程序全局变量、函数局部变量

n,s = 10,100    #n和s是全局变量
def fact(n):
    s = 1       #fact()函数中的n和s是局部变量
    for i in range(1,n+1) :
        s *= i  
    return s
print(fact(n),s)   # n和s是全局变量

>>>3628800  100

(1)规则一:局部变量和全局变量是不同变量

(觉得是这个样子)函数内部同名变量是一个变量,外部变量和函数内部变量不是一个

-局部变量是函数内部的占位符,与全局变量可能重名但不同

-函数运算结束后,局部变量被释放

-可以用global保留字在函数内部使用全局变量

n,s = 10,100    #n和s是全局变量
def fact(n):    #fact()函数中使用global保留字声明
    global s    #此处s是全局变量s
    for i in range(1,n+1) :
        s *= i
    return s    #此处s指全局变量s
print(fact(n),s)  #此处全局变量s被函数修改

 运行结果:362880000 362880000

global: 

# 全局变量:定义在函数外部的变量,拥有全局的作用域
num = 125
# print(num)

def show():
    global num
    # 全局变量只能使用,不能修改
    # 直接赋值不是修改全局变量,而是定义一个同名的局部变量
    '''若想要修改全局变量,想要使用global进行声明,若想改变内部函数的内部函数的...同变量,
    每层都global 同变量下去,编写一下理解吧'''
    def test():
        global num
        num = 20
        print(num)
    test()

show()
print(num)

运行结果:
20

nonlocal:

def wai():
    n = 100

    def nei():
        # 可以使用外部函数的局部变量,但是不能修改
        # 直接赋值相当于重新定义了一个局部变量
        ''' 若想修改,效益使用nonlocal进行声明,若函数最内层定义一个 nonlocal变量可改变最外层函数内部所有同名变量值'''
        nonlocal n
        n = 10
        print(n)

    nei()
    print(n)
  
wai()  

(2)规则二:局部变量为组合数据类型且未创建,等同于全局变量

ls = ["F","f"]   #通过使用[]真实创建了一个全局变量列表ls
def func(a):
    ls.append(a) #此处ls是列表类型,未真实创建,则等同于全局变量
    return
func("C")        #全局变量ls被修改
print(ls)

运行结果:['F', 'f', 'C']

ls =["f","F"]    #通过使用[]真实创建了一个全局变量列表ls
def func2(a):
    ls = []      #此处ls是列表类型,真实创建,ls是局部变量
    ls.append(a)
func2("C")       #局部变量ls被修改 
print(ls) 

运行结果:['f', 'F']

(3)使用规则

-基本数据类型,无论是否重名,局部变量与全局变量不同

-可以通过global保留字在函数内部声明全局变量

-组合数据类型,如果局部变量未真实创建,则是全局变量

附:块级作用域

if True:
    a = 250

#代码块外面可以使用,说明没有块级作用域
print(a)

5、lambda函数(匿名函数)

(1)函数可以像普通函数一样赋值

def test():
    print('for test')
    
# 获取函数的名字
print(test.__name__)

# 函数可以像普通变量一样进行赋值
a = test
print(a.__name__)

# 同样可以调用
a()

(2)函数可以作为另一个函数的参数

# 函数作为另一函数的参数
def demo(func):
    func()

demo(test)

(3)lambda函数返回函数名作为结果

-lambda函数是一种匿名函数,即没有名字的函数

-使用lambda保留字定义,函数名是返回结果,不需要return返回

-lambda函数用于定义简单的、能够在一行内表示的函数

<函数名> = lambda <参数>:<表达式>
#等价于:
     def <函数名>(<参数>):
         <函数体>
         return <返回值>
#pycharm:
f = lambda x,y:x+y
print(f(10,15))
f1=lambda:"lambda函数"
print(f1())

#python:
>>>f = lambda x,y:x+y
>>>f(10,15)

25

>>>f =lambda:"lambda函数"
>>>print(f())

lambda函数
def calc(a, b, suanfa):
    return suanfa(a, b)

def add(x, y):
    return x + y

print(calc(3, 5, add))
# 通过匿名函数实现,更加方便简洁
print(calc(3, 5, lambda x, y: x + y))



# lt = [1, 4, 9, 7, 5, 2, 3]
lt = [
    {'name': 'ergou', 'age': 18, 'weight': 60},
    {'name': 'dagou', 'age': 19, 'weight': 65},
    {'name': 'erhua', 'age': 16, 'weight': 50},
    {'name': 'dahua', 'age': 20, 'weight': 55},
]

def key(d):
    return d['age']

#两种方式:1、def定义函数调用  2、lambda
#lt.sort(key=key)
lt.sort(key=lambda d: d['weight'])

for i in lt:
    print(i)

(4)谨慎使用lambda函数

-lambda函数主要用作一些特定函数或方法的参数

-lambda函数有一些固定使用方式,建议逐步掌握

-一般情况,建议使用 def 定义的普通函数

小结:

-使用保留字  def  定义函数, lambda 定义匿名函数

-可选参数(赋初值)、可变参数(*b)、名称传递

-保留字 return 可以返回任意多个结果

-保留字 global 声明使用全局变量,一些隐式规则

6、闭包使用

闭包可以看做是具有执行环境的函数    

  • 外部函数中定义一个内部函数
  • 内部函数中使用外部函数变量
  • 外部函数将内部函数作为返回值返回
  • 返回的函数就叫闭包
def wai(n):
    # 定义内部函数
    def nei():
        # 使用外部函数的局部变量
        return n * n

    # 函数作为返回值返回
    return nei
    
# 返回的就是闭包
f1 = wai(10)
f2 = wai(5)

print(f1())
print(f2())    

7、装饰器

作用:当需要修改函数的功能,有无法/不想修改原来的函数时,通过装饰器进行解决

使用:

  • 装饰器就是一个函数,该函数具有一个我参数(函数类型),返回一个闭包
  • 在闭包中调用传递进来的函数,在调用函数的前后就可以添加内容了
def zhuangshiqi(func):
    def wrapper():
        print('======')
        func()
        print('******')
    return wrapper

@zhuangshiqi # 等价于:test = zhuangshiqi(test)
def test():
    print('for test')

# test()
# test = zhuangshiqi(test)
test()

运行:
======
for test
******

标准装饰器:可以任意类型的函数(参数、返回值不限制)

def zhuangshiqi(func):
    # 接纳任意的参数形式
    def wrapper(*args, **kwargs):
        print('xxx')
        ret = func(*args, **kwargs)
        print('yyy')
        # 返回对应的返回值
        return ret
    return wrapper

@zhuangshiqi
def test(n):
    print('My lucky number is {}'.format(n))
    return n * n

print(test(7))

运行结果:
xxx
My lucky number is 7
yyy
49

猜你喜欢

转载自blog.csdn.net/qq_34195441/article/details/87943419