栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Python 函数

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python 函数

图片来源于网易课堂,大熊课堂

文章目录

什么是函数?

函数的定义 

普通参数

默认参数

关键字参数

不定长参数

函数的返回值

函数的作用域

函数嵌套

递归函数

匿名函数

创建匿名函数

函数装饰器

体验函数装饰器 

创建装饰器

 带参数的装饰器

不定长参数的装饰器

装饰器嵌套


什么是函数?

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

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

(菜鸟教程)

函数的定义 
注: 函数定义完,不会自动执行,需要自己调用

示例:

def get_requests():
    print("hello")
    print("函数先定义后调用哦")

# 调用
get_requests()

>>> hello
    函数先定义后调用哦

普通参数

示例:

def book(one, two):
    print(one)
    print(two)
book('1', '2')

>>> 1
    2

 由此可见,函数的普通参数是一一对应着的。

默认参数

假设我今天工作了十个小时,我的工资是每小时八块钱这是我的固定工资,那我今天应得 八十。

def working(hours, compensation=8):
    print(f'你今天工作了 {hours} 小时, 现工资为:{hours * compensation}')
working(10)

>>> 你今天工作了 10 小时, 现工资为:80

节假日我的每小时工资提高到了 20 元/时,这时我的应得工资为 200

def working(hours, compensation=8):
    print(f'你今天工作了 {hours} 小时, 现工资为:{hours * compensation}')
working(10, 20)

>>> 你今天工作了 10 小时, 现工资为:200

由此可见,当设置了默认参数时,不重新定义参数则使用默认参数。

关键字参数

  关键字参数的位置不需要一一对应,因为它是使用直接赋值的方式.

def hero(name, nickname):
    print(f'{nickname}:{name}')
hero(name='鲁智深', nickname='花和尚')

>>> 花和尚:鲁智深

不定长参数

简单说就是参数的长度不固定。

1. 第一种,单个星号的情况

  在这里rags相当于一个容器,它包含着你传递过来的所有参数,默认将参数转化为元组。

def number(*args):
    print(args)
    for i in args:
        print(i)
        
number(1, 2, 3, 4, 5, 6, 7, 8, 9)

>>> (1, 2, 3, 4, 5, 6, 7, 8, 9)
    1
    ...
    9

2. 第二种俩星号的情况

这个也是一个不定长参数,唯一不一样的是它转换的是字典类型。

def number(*args, **kwargs):
    print(args)
    print(kwargs)


number(1, 2, 3, 4, 5, 6, 7, 8, 9, name='鲁智深', nickname='花和尚')

>>> (1, 2, 3, 4, 5, 6, 7, 8, 9)
    {'name': '鲁智深', 'nickname': '花和尚'}

函数的返回值

什么的返回值,简单说就是程序执行完成后得出的结果。

图片:大熊课堂

 示例:

def add(one, two):
    return one + two

# 结果最终返回给了调用者,我们也可以给它赋值
print(add(5, 6))

>>> 11

函数的作用域
  • 局部变量

        简单说局部变量就是函数内部定义的变量,局部变量与局部变量之间没有任何关系。例如:

def one():
    a = 100
    print(a)
def two():
    a = 200
    print(a)
one()
two()

>>> 100
    200
  • 全局变量

        全局变量即函数外定义的变量,即可以被函数内部调用。

one = 4
def add():
    print(one)
add()

>>> 4

就近原则

当然函数内部没有定义使用,使用全局变量,如内部以定义则使用局部变量。

one = 1

def add():
    print(one)
def two():
    one = 5
    print(one)
add()
two()
print(one)

>>> 1
    5
    1

1. 在函数修改全局变量

这是不被允许的,因为内部没有定义,但如果我声明了全局变量就可以修改了。

one = 4
def add():
    one += 1
add()

>>> UnboundLocalError: local variable 'one' referenced before assignment
one = 4
def add():
    global one
    one += 1
    print(one)
add()
print(one)

>>> 5
    5

2. 局部使用全局变量,可变类型

  这是被允许的,因为列表是可变类型动态的。

one = [1, 2, 3, 4, 5]
def add():
    one.append(6)
    print(one)
add()

>>> [1, 2, 3, 4, 5, 6]

总结:
局部变量:

  1.  局部变量,函数内部定义的变量
  2. 不同函数可以有相同的变量名,不会产生影响
  3. 它的作用是临时保存函数中使用的数据

全局变量:

  1. 全局变量,函数外部定义的变量
  2. 对于不可变类型的全局变量,需要使用global修改全局变量
  3. 对于可变类型的全局变量,不使用global也可以修改

函数嵌套

1. 函数中调用其他函数

def start():
    one()
    two()


def one():
    print('one 开始执行')
    print('one 执行完成')


def two():
    print('two 开始执行')
    print('two 执行完成')

start()

>>> one 开始执行
    one 执行完成
    two 开始执行
    two 执行完成

2. 在函数中创建函数

  注:函数内部创建的函数,只能在内部调用

def start():
    print('Start 开始')
    def over():
        print('Over 开始执行')
    over()
start()

>>> Start 开始
    Over 开始执行

3. 函数嵌套中的变量作用域

  可以看出,这里的作用域与前面说的局部全局很相似,内部函数 over 没有声明变量 a 也可以调用 start 函数中的 a ,也就是如果在函数内部找不到变量 a 就去函数外面查找。

def start():
    a = 10
    print(f'start 中的a值为{a}')

    def over():
       a = 200
       print(f'over 中的a值为{a}')
    over()
start()


>>> start 中的a值为10
    over 中的a值为200

4. 函数嵌套,修改外函数的变量

 修改外函数变量需要使用关键字 nonlocal 

def start():
    a = 10
    print(f'start 中的a值为{a}')

    def over():
       nonlocal a
       a = 200
       print(f'over 中的a值为{a}')
    over()
    print(f'外函数:{a}')
start()

>>> start 中的a值为10
    over 中的a值为200
    外函数:200

递归函数

在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数

图片:大熊课堂

 示例:

  求阶层例子

def fact(n):
    if n == 1:
        return 1
    resutl = n * fact(n-1)
    return resutl
result = fact(3)
print(result)

>>> 6

匿名函数

匿名函数,顾名思义即没有名字,匿名函数一般用于实现功能简单简短的函数。

创建匿名函数
图片:大熊课堂

 语法结构

图片:大熊课堂

 示例:

def add(x, y):
    return x + y
print(add(1, 3))

adds = lambda x, y: y + x
print(adds(1, 3))

addpuls = (lambda x, y: y + x)(1, 3)
print(addpuls)


>>> 4
    4
    4

函数装饰器

装饰器(Decorators)是 Python 的一个重要部分。简单地说:他们是修改其他函数的功能的函数。他们有助于让我们的代码更简短,也更Pythonic(Python范儿)

(菜鸟教程)

如果还不是很明白,那我们举个栗子吧,圣诞节到了很多商城都买了圣诞树放在门口,而树上的装饰品就类似于我们的装饰器,而树的本身还是树。

体验函数装饰器 

我们以一个计算函数运行时间的例子来演示。

1. 普通方式计算

  像我们以前都是这样计算的,设想一下如果你要计算很多函数的运行时间,你是不是得写很多 开始时间,结束时间啥的哈,这样一来我们的代码就会非常的臃肿.

import time

def time_for():
    print('time_for 开始')
    for i in range(1000000):
        pass
    print('time_for 结束')

# 开始时间
start_time = time.perf_counter()
time_for()
# 结束时间
end_time = time.perf_counter()
print(f'time_for 运行时间为:{end_time - start_time}')


>>> time_for 开始
    time_for 结束
    time_for 运行时间为:0.021750199999999997

2. 利用函数的方式

  使用函数的方式,可以让我们的代码更加简单,但还是很麻烦,这时我们的函数装饰器就出现了,下面我们就以函数装饰器来更改这个例子.

import time

# 计算程序运行时间函数
def my_time(func):
    def operation():
        print('operation 开始')
        start_time = time.perf_counter()
        func()
        end_time = time.perf_counter()
        print(f'函数运行时间:{end_time - start_time}')
        print('operation 结束')
    return operation

# 待计算函数 (一)
def time_for():
    for i in range(1000000):
        pass

# 待计算函数(二)
def time_while():
    i = 0
    while i < 1000000:
        i += 1

# 计算 time_for
result = my_time(time_for)
result()
print('n')
# 计算 time_while
new_resule = my_time(time_while)
new_resule()


>>> operation 开始
    函数运行时间:0.022555599999999995
    operation 结束


    operation 开始
    函数运行时间:0.0553232
    operation 结束

3. 使用函数装饰器的方式

  我们可以发现这个代码,比我们之前的都简洁而且更加的易于阅读,这就是函数装饰器(语法糖/魔法糖)它使用 @ 来表示装饰.

import time

# 计算程序运行时间函数
def my_time(func):
    def operation():
        print('operation 开始')
        start_time = time.perf_counter()
        func()
        end_time = time.perf_counter()
        print(f'函数运行时间:{end_time - start_time}')
        print('operation 结束')
    return operation

# 待计算函数 (一)
@my_time
def time_for():
    for i in range(1000000):
        pass

# 待计算函数(二)
@my_time
def time_while():
    i = 0
    while i < 1000000:
        i += 1

# 计算 time_for 运行时间
time_for()

# 计算 time_while 运行时间
time_while()


>>> operation 开始
    函数运行时间:0.0339201
    operation 结束
    operation 开始
    函数运行时间:0.0529231
    operation 结束

创建装饰器

因为这个内容不好讲,我也不会怎么讲怕误人子弟,这里就引入菜鸟教程的课程。

函数装饰器-菜鸟教程https://www.runoob.com/w3cnote/python-func-decorators.htmlhttps://www.runoob.com/w3cnote/python-func-decorators.html

 带参数的装饰器

  代码解析:我们都知道代码从上至下开始运行,遇到函数不会自动执行,遇到 time_for 函数调用才开始执行,因为 time_for 被装饰了使用相当于调用了 my_time 而传递的参数就是 numbers,因为我们的主函数是 operation 所以自然而然的传递给它,剩下的就是传递给 func.

import time


# 计算程序运行时间函数
def my_time(func):
    def operation(numbers):
        print('operation 开始')
        start_time = time.perf_counter()
        func(numbers)
        end_time = time.perf_counter()
        print(f'函数运行时间:{end_time - start_time}')
        print('operation 结束')

    return operation


# 待计算函数 (一)
@my_time
def time_for(numbers):
    for i in range(numbers):
        pass


time_for(10000)


>>> operation 开始
    函数运行时间:0.0004415000000000044
    operation 结束

不定长参数的装饰器

      在前面我们介绍过函数的不定长参一个 * 代表的元组,俩个 * 代表的字典,那么对于我们的装饰器我们该怎么书写呢?

图片:大熊课堂

 不定长参数的传递位置跟普通参数传递位置是一样的,这里只拿 单个 * 号做示例,kwargs 的方法也是如此,不同的是 kwaargs 传递时是以关键字的方式传递的.

import time


# 计算程序运行时间函数
def my_time(func):
    def operation(*args):
        print('operation 开始')
        start_time = time.perf_counter()
        func(*args)
        end_time = time.perf_counter()
        print(f'函数运行时间:{end_time - start_time}')
        print('operation 结束')

    return operation


@my_time
def welcome(*args):
    name, gender = args
    gender = '男士' if gender == '男' else '女士'
    print(f'{name}{gender}, 新天地红楼欢迎您!')


welcome('赵日天', '男')

>>> operation 开始
	赵日天男士, 新天地红楼欢迎您!
	函数运行时间:8.099999999996998e-06
	operation 结束

装饰器嵌套

 函数装饰器嵌套,直白说就是一个函数引用了多个装饰器的情况,装饰器嵌套调用时需要注意它的顺序,先调用离它最近的装饰器.

图片:大熊课堂

 示例:

def my_one(func):
    def my_decoration_one(name):
        func(name)
        print('my_one 函数启动')
    return my_decoration_one

def my_two(func):
    def my_decoration_two(name):
        print('my_two 函数启动')
        func(name)
    return my_decoration_two

@my_one
@my_two
def welcome(name):
    print(f'代号:{name}')


welcome('赵日天')

>>> my_two 函数启动
    代号:赵日天
    my_one 函数启动

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/339675.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号