什么是函数?

函数无非就是将代码块进行封装,想用的时候拿来用,减少代码量,提高效率。

函数的定义

定义一个函数需要:

1.def关键字,def 后面空一格输入函数名称,函数命名时尽量简短,且具有意义,能通过函数名窥见该函数实所实现的功能,函数名称后面紧跟着一对英文圆括号()和英文冒号:

def关键字、函数名、括号、冒号缺一不可

2.括号里面存放参数,根据需要可传可不传

3.一般使用三重引号注释函数所实现功能,并放于第一行(根据编码者习惯可写可不写)

4.冒号以下都是函数内容

5.return 可写可不写,根据实际情况,若不填写时,该函数无返回值

def my_fun(parameters):
"""
实现XXXXX功能
:return:
"""
Function body return expression

定义一个简单的函数

def marks():
"""
分数校验
:return:
"""
mark = float(input("请输入分数:"))
if mark < 60:
return False
else:
return True

函数定义后不会执行,需要调用才会去执行

 函数的调用

def sub(a, b):
"""
实现减法
:param a:
:param b:
:return:
"""
return a - b result = sub(2, 5)
print(result)
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py
-3

或者由其他函数调用执行

import random
import string
import hashlib def random_str(number):
"""
生成随机码
:param number:
:return:
"""
code = ''.join(random.sample(string.digits + string.ascii_letters, int(number)))
return code def md5_str(number):
"""
md5加密
:param number:
:return:
"""
md5_data = hashlib.md5()
md5_data.update(random_str(number).encode()) # 调用random_str()函数生成随机数
sign = md5_data.hexdigest()
return sign if __name__ == '__main__':
string = md5_str(8)
print(string)
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py
345b36fc3ee89f786bc122cb3f8c26f2

参数使用

上面的例子中已用到了参数,在python实际使用中,参数分为形参、实参

形参:定义函数时传递的参数

实参:调用函数时传递的参数

def len_str(data):  # 形参 data
"""
获取字符串长度
:param data:
:return:
"""
count = 0
for i in data:
count += 1
return count print(len_str("If you plant a melon, you get a melon")) # 传入实参
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py
37

位置参数(必备参数)

调用时传入的参数必须与声明中的参数一一对应,包括位置、数量、参数类型

def max_data(da):
"""
获取列表中最大值
:param da:
:return:
"""
for i in range(len(da) - 1):
for j in range(len(da)-1 - i):
if da[j] > da[i]:
temp = da[j]
da[j] = da[j+1]
da[j+1] = temp
return da[len(da) - 1] print(max_data())
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py
Traceback (most recent call last):
File "D:/demo/funtion_1.py", line 63, in <module>
print(max_data())
TypeError: max_data() missing 1 required positional argument: 'da'
def student(name, age):
stu = {"张三": 19, "李四": 20, "王二": 19, "麻子": 20}
for key, value in stu.items():
if name == key and age == value:
return "该考生存在" print(student(19, "王二")) # name 对应19, age 对应王二
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py
查无此人
def student(name, age):
stu = {"张三": 19, "李四": 20, "王二": 19, "麻子": 20}
for key, value in stu.items():
if name == key and age == value:
return "该考生存在" print(student("王二", 19)) # name 对应王二, age 对应19
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py
该考生存在

关键字参数

关键字参数是指在调用时,使用形参名+传入的参数值(parameter1=value1,parameter2=value2),使用关键字参数时不需要与声明中的位置对应

def student(name, age):
stu = {"张三": 19, "李四": 20, "王二": 19, "麻子": 20}
for key, value in stu.items():
if name == key and age == value:
return "该考生存在" print(student(age=19, name="王二")) # name、age 位置可不对应
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py
该考生存在

位置参数与关键字参数混合使用

混合使用时,位置参数一定要在关键字参数前,不然程序报错,不可执行

def student(name, age):
stu = {"张三": 19, "李四": 20, "王二": 19, "麻子": 20}
for key, value in stu.items():
if name == key and age == value:
return "该考生存在" print(student(age=19, "王二")) # 当关键字参数在位置参数前时抛出"位置参数必须在关键字参数前"
  File "D:/demo/funtion_1.py", line 73
print(student(age=19, "王二")) # 当关键字参数在位置参数前时抛出"位置参数必须在关键字参数前"
^
SyntaxError: positional argument follows keyword argument
def student(name, age):
stu = {"张三": 19, "李四": 20, "王二": 19, "麻子": 20}
for key, value in stu.items():
if name == key and age == value:
return "该考生存在" print(student("王二", age=19,))
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py
该考生存在

关键字参数与位置参数混合使用,容易出现一个坑,TypeError: xxxxx() got multiple values for argument xxxxx'

def student(name, age):
stu = {"张三": 19, "李四": 20, "王二": 19, "麻子": 20}
for key, value in stu.items():
if name == key and age == value:
return "该考生存在" print(student(19, name="王二"))
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py
Traceback (most recent call last):
File "D:/demo/funtion_1.py", line 73, in <module>
print(student(19, name="王二"))
TypeError: student() got multiple values for argument 'name'

默认参数

默认参数是指在定义时传入参数值,调用时未传入参数则使用默认传入的参数值,否则使用调用传入的参数值


def marks(mark=60):
mar = float(input("请输入你的分数"))
if mar > mark:
return "及格线为: %s, 你及格了" % mark
else:
return "及格线为: %s, 你需要补考" % mark print(marks(85)) # 传入参数,此时使用调用时传入的参数值
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py
请输入你的分数80
及格线为: 85, 你需要补考
def marks(mark=60):
mar = float(input("请输入你的分数"))
if mar > mark:
return "及格线为: %s, 你及格了" % mark
else:
return "及格线为: %s, 你需要补考" % mark print(marks()) # 不传入参数,此时使用定义时传入的参数值
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py
请输入你的分数80
及格线为: 60, 你及格了

动态参数

动态参数又称为不定长参数,在使用时,根据需要可以传入任意个参数,动态参数有两种形式,*args, **kwargs,参数间的位置排序为:位置参数、默认参数、*args动态参数、**kwargs动态参数、关键字参数

*args: 表示接受任意多个实际参数将其放到一个元组中,如果参数是个列表,会将整个列表当做一个参数传入

def marks(*args):
print(args)
for i in args:
print(i) (marks(["张三", "李四", "王二", "麻子"], [50, 50, 70, 90]))
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py
(['张三', '李四', '王二', '麻子'], [50, 50, 70, 90])
['张三', '李四', '王二', '麻子']
[50, 50, 70, 90]

以上是将列表当成一个参数,若要分解成多个参数,调用时可以在参数前加 *,也称为解包(适用于任何序列类型数据对象)

def marks(*args):
print(args)
for i in args:
print(i) (marks(*["张三", "李四", "王二", "麻子"], *[50, 50, 70, 90]))
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py
('张三', '李四', '王二', '麻子', 50, 50, 70, 90)
张三
李四
王二
麻子
50
50
70
90
def marks(*args):
print(args)
for i in args:
print(i) (marks(*{"张三": 95, "李四": 20, "王二": 88, "麻子": 91})) # 将字典中的key作为参数
('张三', '李四', '王二', '麻子')
张三
李四
王二
麻子

**kwargs:表示接受任意多个实际参数将其放到一个字典中,类似关键字参数

def marks(**kwargs):
print(kwargs)
for name, mark in kwargs.items():
print(name, ":", mark) (marks(张三=90, 李四=20)) # 通过关键字传入
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py
{'张三': 90, '李四': 20}
张三 : 90
李四 : 20
def marks(**kwargs):
print(kwargs)
for name, mark in kwargs.items():
print(name, ":", mark) (marks(**{"张三": 95, "李四": 20, "王二": 88, "麻子": 91})) # 通过字典传入,在参数前加入**,函数会把dict中所有键值对转换为关键字参数传进去
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py
{'张三': 95, '李四': 20, '王二': 88, '麻子': 91}
张三 : 95
李四 : 20
王二 : 88
麻子 : 91

*args, **kwagrs混合使用

def persons(name, age, *args, **kwargs):
print(args)
print(kwargs)
infos = ''
if "王" in name or age < 20:
if kwargs['address'] == "深圳":
for info in args:
infos += info
for k, v in kwargs.items():
print(name, "基础资料有", k, ":", v)
print(name, "年龄在20的深圳小青年,其他信息有", infos) persons("王二", 19, "文艺", "摇滚", address="深圳", job="student")
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py
('文艺', '摇滚')
{'address': '深圳', 'job': 'student'}
王二 基础资料有 address : 深圳
王二 基础资料有 job : student
王二 年龄在20的深圳小青年,其他信息有 文艺摇滚

 函数变量作用域

根据变量的定义位置,决定变量的作用范围

局部变量:定义在函数内部的变量,只在函数内部有效,执行完后,局部变量会被释放,无法再次访问

全局变量:定义在整个文件层次上,可以在整个程序范围内访问

def sum(a, b):
count = a + b
return count # count 局部变量 print(sum(1, 4))
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py
5
guess = -10   # 全局变量

def compare():
times = 3
while times > 0:
value = float(input("请输入你所猜数字, 你还有%s次机会" % times))
if value == guess:
return "恭喜,猜对啦"
else:
times -= 1
return "很遗憾,你的次数用完啦" print(compare())
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py
请输入你所猜数字, 你还有3次机会3
请输入你所猜数字, 你还有2次机会0
请输入你所猜数字, 你还有1次机会9
很遗憾,你的次数用完啦

尝试在函数内修改全局变量

guess = -10   # 全局变量

def compare():
times = 3
while times > 0:
value = float(input("请输入你所猜数字, 你还有%s次机会" % times))
if value == guess:
return "恭喜,猜对啦"
else:
guess = 1
times -= 1
return "很遗憾,你的次数用完啦" print(compare())
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py
请输入你所猜数字, 你还有3次机会24
Traceback (most recent call last):
File "D:/demo/funtion_1.py", line 135, in <module>
print(compare())
File "D:/demo/funtion_1.py", line 127, in compare
if value == guess:
UnboundLocalError: local variable 'guess' referenced before assignment

在函数内部修改全局变量报错了,这是因为,Python 的解释器会默认函数内部的变量为局部变量,然而局部变量 guess 又没有声明,因此就无法执行相关操作。那么如果要在函数内更改全局变量呢?

这里可以引入 global

def compare():
global guess
print("修改前的谜底:%s" % guess)
times = 3
while times > 0:
value = float(input("请输入你所猜数字, 你还有%s次机会" % times))
if value == guess:
return "恭喜,猜对啦"
else:
guess = 1
times -= 1
return "很遗憾,你的次数用完啦", "此时谜底为:%s" % guess print(compare())
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py
修改前的谜底:-10
请输入你所猜数字, 你还有3次机会64
请输入你所猜数字, 你还有2次机会978
请输入你所猜数字, 你还有1次机会3
('很遗憾,你的次数用完啦', '此时谜底为:1')

函数嵌套

函数嵌套是指函数里面又存在函数,经典案例递归

def factorial_calculation():
number = int(input("请输入整数"))
if number <= 0:
return "请输入大于0的正整数" def factorial(number):
if number <= 1:
return 1
return number * factorial(number-1)
return factorial(number) print(factorial_calculation())
"D:\Program Files\Python\Python37-32\python.exe" D:/demo/funtion_1.py
请输入整数6
720

python 之用户自定义函数的更多相关文章

  1. Python学习--05函数

    Python函数 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.我们已经知道Python提供了许多内建函数,比如print().但我们 ...

  2. python中的函数

    Python 函数 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也 ...

  3. python基础之函数

    python 函数 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也 ...

  4. Pig用户自定义函数(UDF)转

    原文地址:http://blog.csdn.net/zythy/article/details/18326693 我们以气温统计和词频统计为例,讲解以下三种用户自定义函数. 用户自定义函数 什么时候需 ...

  5. Python 基础之函数、深浅copy,set及练习

    三元运算符通常在Python里被称为条件表达式,这些表达式基于真(true)/假(not)的条件判断,在Python 2.4以上才有了三元操作. 语法格式: X if C else Y 有了三元表达式 ...

  6. Python基础之函数和模块

    函数的基本使用 函数的定义:把具有独立功能的代码块组织成一个小模块,在需要的时候调用.或者说,函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数的使用:1.定义函数:2.调用函数 ...

  7. python学习日记(函数基础)

    修改文件(原理)--回顾 #修改文件(原理) with open('name','r',encoding='utf-8') as f,\ open('password','w+',encoding=' ...

  8. Python编程基础[函数和面向对象](三)

    Python 函数 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也 ...

  9. 编程入门python之定义函数【转】

    编程入门python之定义函数 零基础学编程by学哥 2017-02-06 10:51 今天讲python函数. 输入参数求三角形或圆形或长方形的面积 先输入1个参数:形状类型 1=三角形 2=圆形 ...

随机推荐

  1. opencv cv.line

    ''' 本次来学习基于opencv进行各种画图操作,以前只习惯用matplotlib,最近开始用opencv,觉得也很好用. cv.line(), cv.circle() , cv.rectangle ...

  2. 空 Maven项目转成 Web项目 & SpringMVC调用其他 Module中的方法可能会遇到的小问题

    SpringMVC调用其他 模块内的方法的 坑 下次别在阴沟里翻船啦.. 一共花费 4个小时,解决项目中的这个问题 OMG 1. 首先是 Maven新建工程 一般使用 Maven都是先创建 空工程 当 ...

  3. 插件化编程之WebAPI统一返回模型

    WebApi返回数据我们一般包裹在一个公共的模型下面的,而不是直接返回最终数据,在返回参数中,显示出当前请求的时间戳,是否请求成功,如果错误那么错误的消息是什么,状态码(根据业务定义的值)等等.我们常 ...

  4. 文心ERNIE-ViLG,你的免费插图画师

    你是否想拥有一个专属画师,免费为你的优美文字插上几幅优美的插图?如今依然实现 最近AI作画确实很火,在DALL-E和Imagen崭露头角之后,ERNIE-ViLG.Stable-Diffusion(S ...

  5. Oracle注入

    Oracle 查询出所有的表 select * from all_tables 查询出当前用户的表 select * from user_tables 查询出所有的字段 select*from all ...

  6. centos7搭建安装loki、promtail、Grafana日志系统

    loki.promtail.Grafana安装包 链接:https://pan.baidu.com/s/1vkSa_KYrXM0UEI8i42KdaA 提取码:4d4q 如果安装失败或者下载速度慢可以 ...

  7. 动词时态=>2.动作的时间状态结合

    动作和时间结合 现在的四种时态 现在进行时态 对于 现在这个时间点,这个 动作 还在进行当中 例如:我现在正在喝水 现在完成时态 对于 现在这个时间点,这个 动作 已然完成 例子:我现在已经喝完了水 ...

  8. C#实现生成Markdown文档目录树

    前言 之前我写了一篇关于C#处理Markdown文档的文章:C#解析Markdown文档,实现替换图片链接操作 算是第一次尝试使用C#处理Markdown文档,然后最近又把博客网站的前台改了一下,目前 ...

  9. .NET 7 AOT 的使用以及 .NET 与 Go 互相调用

    目录 背景 C# 部分 环境要求 创建一个控制台项目 体验 AOT 编译 C# 调用库函数 减少体积 C# 导出函数 C# 调用 C# 生成的 AOT Golang 部分 安装 GCC Golang ...

  10. Spring Cloud Loadbalancer

    Spring Cloud Loadbalancer---客户端负载均衡器 springcloud 2020.0.1 版本之后 删除了eureka中的ribbon,替代ribbon的是spring cl ...