Python 函数定义和使用
# 函数的概念
# 概念
# 写了一段代码实现了某个小功能; 然后把这些代码集中到一块, 起一个名字; 下一次就可以根据这个名字再次使用这个代码块, 这就是函数
# 作用
# 方便代码的重用
# 分解任务, 简化程序逻辑
# 使代码更加模块化
# 函数分类
# 内建函数
# 三方函数
# 自定义函数 # 函数的基本使用
# 简单定义
# def 函数名():
# 函数体
# 函数的调用
# 函数名()
def myFun():
print(1) #函数调用
myFun() # 函数的参数
# 单个参数
# 场景
# 需要动态的调整函数体中某一个处理信息
# 则可以, 以参数的形式接收到相关数据
# 定义
# def 函数名(参数名称):
# 函数体
# 函数体中, 可以直接以变量的方式使用该参数
# 函数的调用
# 函数名(参数值)
# 形参和实参的概念
# 上述函数定义中, "参数名称"即为形参;
# 在调用函数的时候, 传递的真实数据, 即为实参
# 多个参数
# 场景
# 需要动态的调整函数体中多个处理信息时
# 则可以以 逗号 做分割, 接收多个参数
# 定义
# def 函数名(参数名称1, 参数名称2):
# 函数体
# 函数体中, 可以直接以变量的方式使用所有参数
# 调用
# 方式1
# 函数名(参数1, 参数2, 参数3...)
# 形参和实参一一对应
# 方式2
# 函数名(参数名称1=参数1, 参数名称n = 参数n...)
# 可以指明形参名称
# 称为"关键字参数"
# 不需要严格按照顺序 # 不定长参数
# 场景
# 如果函数体中, 需要处理的数据, 不确定长度
# 则可以以不定长参数的方式接收数据
# 方式1
# 定义
# def 函数名(*args):
# 元组
# 函数体
# 函数体中, 可以直接以元组变量的方式使用该参数
# 使用
# 函数名(参数1, 参数2, 参数3...)
def myFunA(*args):
print(args,type(args))
for v in args:
print(v) myFunA(1, 2, 3) #(1, 2, 3) <class 'tuple'> # 方式2
# 定义
# def 函数名(**dic):
# 字典
# 函数体
# 函数体中, 可以直接以字典变量的方式使用该参数
# 使用
# 函数名(参数名称1=参数1, 参数名称2=参数2...)
def myFunB(**kwargs):
print(kwargs, type(kwargs)) myFunB(name = "abc", age = 18) # {'name': 'abc', 'age': 18} <class 'dict'> # 参数拆包
# 装包
# 把传递的参数, 包装成一个集合, 称之为"装包"
# 拆包
# 把集合参数, 再次分解成单独的个体, 称之为"拆包"
def mySum(a, b):
print(a + b) def myFunC(*args):
print(args)
#拆包
mySum(*args) myFunC(1, 2) #(1, 2) 3 # 缺省参数
# 场景
# 当我们使用一个函数的时候, 如果大多数情况下, 使用的某个数据是一个固定值, 或者属于主功能之外的小功能实现;
# 则可以使用默认值
# 这种参数, 称为"缺省参数"
# 定义
# def 函数名(变量名1=默认值1, 变量名2=默认值2):
# 函数体
# 函数体中, 即使外界没有传递指定变量, 也可以使用, 只不过值是给定的默认值
# 使用
# 函数名(变量1, 变量2)
# 此处如果是缺省参数, 则可以不填写 # 参数注意
# 值传递和引用传递
# 值传递
# 是指传递过来的, 是一个数据的副本;
# 修改副本, 对原件没有任何影响
# 引用传递
# 是指传递过来的, 是一个变量的地址
# 通过地址, 可以操作同一份原件
# 但是注意
# 在Python当中, 你没得选, 只有引用传递(地址传递)
# 但是
# 如果数据类型是可变类型, 则可以改变原件
# 如果数据类型是不可变类型, 则不可以改变原件 def test(num):
print(id(num))
print(num)
num = 11
print(id(num)) # 和a地址不一样
a = 10
print(id(a))
test(a) # 打印的id 值一样
print(id(a))
print("------------------") # 值发生改变,是根据数据类型来说的
def test1(num):
print(id(num))
num.append(666)
a = [1, 2, 3]
print(id(a))
test1(a) # 打印的id 值一样
print(a) #[1, 2, 3, 666] # 函数的返回值
# 场景
# 当我们通过某个函数, 处理好数据之后, 想要拿到处理的结果
# 语法
# def 函数():
# 函数体
# return 数据
# 注意事项
# 1. return 后续代码不会被执行
# 2. 只能返回一次
# 3. 如果想要返回多个数据, 可先把多个数据包装成一个集合, 整体返回
# 列表
# 元组
# 字典
# ... def myCall(a, b):
he = a + b
cha = a - b
return (he, cha) # 返回元组,就可以返回多个值了 he, cha = myCall(11, 10)
print(he, cha) #21 1 # 函数的使用描述
# 场景
# 当我们编写三方函数, 为了方便他人使用, 就需要描述清楚我们所写的函数功能以及使用方式等信息
# 定义格式
# 直接在函数体的最上面, 添加三个双引号对注释
# def 函数():
# ''' 这里写帮助信息 '''
# 查看函数使用文档
# help(函数)
# 经验
# 一般函数的描述, 需要说明如下几个信息
# 函数的功能
# 参数
# 含义
# 类型
# 是否可以省略
# 默认值
# 返回值
# 含义
# 类型 def caculate(a, b = 1):
"""
计算2个数的和与差
:param a: 参数1:数值类型,不可选,没有默认值
:param b: 参数2:数值类型,可选,默认值:1
:return:返回的是计算的结果:元组类型,(和,差)
"""
he = a + b
cha = a - b
return (he, cha) # 返回元组,就可以返回多个值了 help(caculate) # 偏函数
# 概念&场景
# 当我们写一个参数比较多的函数时, 如果有些参数, 大部分场景下都是某一个固定值, 那么为了简化使用, 就可以创建一个新函数,
# 指定我们要使用的函数的某个参数, 为某个固定的值; 这个新函数就是"偏函数"
# 语法
# 方式1
# 自己写一个新的
# 方式2
# 借助functools模块的partial函数
# import functools
# newFunc = functools.partial(函数, 特定参数=偏爱值)
# 场景
# int()
#方式1
def myFun1(a, b, c, d):
print(a + b + c + d) def myFun2(a, b, c, d = 1):
myFun1(a, b, c, d) myFun2(1, 2, 3) #print 7 #方式2
import functools
newFun = functools.partial(myFun1, d = 2)
newFun(1, 2, 3) #print 8 #应用场景
numStr = ""
res = int(numStr, base = 2)
print(res) #print 18
int2 = functools.partial(int, base = 2)
print(int2(numStr)) #print 18 # 高阶函数
# 概念
# 当一个函数A的参数, 接收的又是另一个函数时, 则把这个函数A成为是"高阶函数"
# 例如
# sorted函数
# 案例
# 动态计算两个数据 l = [{"name": "a1", "age": 18}, {"name": "a2", "age": 20}, {"name": "a3", "age": 19}]
def getKey(x):
return x["age"] #按age的值来排序
result = sorted(l, key = getKey)
print(result) # [{'name': 'a1', 'age': 18}, {'name': 'a3', 'age': 19}, {'name': 'a2', 'age': 20}] #案例
def caculate_test(num1,num2, newFun):
return newFun(num1, num2) def sum(a, b):
return a + b res = caculate_test(1, 2, sum)
print(res) # # 返回函数
# 概念
# 是指一个函数内部, 它返回的数据是另外一个函数; 把这样的操作成为"返回函数"
# 案例
# 根据不同参数, 获取不同操作, 做不同计算
def getFunc(flag):
def sum(a, b, c):
return a + b + c
def jian(a, b, c):
return a - b - c if flag == "+":
return sum
elif flag == "-":
return jian newFun = getFunc("+")
res = newFun(1, 2, 3)
print(res) # # 匿名函数
# 概念
# 也称为 "lambda函数"
# 顾名思义, 就是指没有名字的函数
# 语法
# lambda 参数1, 参数2.. : 表达式
# 限制
# 只能写一个表达式
# 不能直接return
# 表达式的结果就是返回值
# 所以, 只适用于一些简单的操作处理
# 测试
# func = lambda x, y: x + y
# func(1, 2) result = (lambda x, y : x + y)(1, 2)
print(result, type(result)) #3 <class 'int'> newFunc = lambda x, y : x + y
print(newFunc(4,5)) # #应用场景
l = [{"name": "a1", "age": 18}, {"name": "a2", "age": 20}, {"name": "a3", "age": 19}]
result = sorted(l, key = lambda x : x["age"])
print(result) # [{'name': 'a1', 'age': 18}, {'name': 'a3', 'age': 19}, {'name': 'a2', 'age': 20}] # 闭包
# 概念
# 在函数嵌套的前提下
# 内层函数引用了外层函数的变量(包括参数)
# 外层函数, 又把 内层函数 当做返回值进行返回
# 这个内层函数+所引用的外层变量, 称为 "闭包"
# 标准格式
# def test1(a):
# b = 10
# 其他函数定义代码
# def test2():
# print(a)
# print(b)
# return test2
# 应用场景
# 外层函数, 根据不同的参数, 来生成不同作用功能的函数
# 案例
# 根据配置信息, 生成不同的分割线函数
# 注意事项
# 1. 闭包中, 如果要修改引用的外层变量
# 需要使用 nonlocal 变量 声明
# 否则当做是闭包内, 新定义的变量
# 2. 当闭包内, 引用了一个, 后期会发生变化的变量时, 一定要注意
# 函数, 是被调用时, 才去确定变量标识所对应的值 #应用场景
def line_config(content,length):
print("-" * (length // 2) + content + "-" * (length // 2)) line_config("闭包",20) #----------闭包----------
line_config("闭包",20) #----------闭包----------
#上面的方式调用麻烦,现在改造一下,方便调用 def line_config(content,length):
def line():
print("-" * (length // 2) + content + "-" * (length // 2))
return line line1 = line_config("闭包",20)
line1() #----------闭包----------
line1() #----------闭包---------- line2 = line_config("闭包",40)
line2() #--------------------闭包-------------------- # 装饰器
# 作用
# 在函数名以及函数体不改变的前提下, 给一个函数附加一些额外代码
# 语法
# @装饰器
# def 被装饰函数():
# code
# 案例
# 发说说, 发图片
# 附加
# 身份验证 操作
# "开放封闭"原则
# 已经写好的代码, 尽可能不要修改
# 如果想要新增功能, 在原先代码基础上, 单独进行扩展
# 单一职责
# 注意
# 装饰器的执行时间, 是立即执行
# 进阶
# 装饰器叠加
# 从上到下装饰
# 从下到上执行
# 对有参函数进行装饰
# 无论什么场景, 保证函数调用参数个数一致
# 为了通用, 可以使用不定长参数, 结合 拆包操作进行处理
# 对有返回值的函数进行装饰
# 无论什么场景, 保证函数返回值一致
# 带有参数的装饰器
# 通过@装饰器(参数)的方式, 调用这个函数, 并传递参数; 并把返回值, 再次当做装饰器进行使用
# 先计算 @ 后面的内容, 把这个内容当做是装饰器 def checkLogin(func):
print("*" * 10 ) # 只在使用@装饰器运行
def inner():
print("登陆认证....")
func()
print("-" * 10) # 函数调用后才运行
return inner @checkLogin # fss = checkLogin(fss)
def fss():
print("发说说") @checkLogin # fpic = checkLogin(fpic)
def fpic():
print("发图片") #下面为业务的逻辑部分,如果要想在程序中保持业务逻辑和代码不变,就需要上面的装饰符
indexItem = 1
if indexItem == 1 :
fss()
else:
fpic() # 生成器
# 生成器
# 是一个特殊的迭代器(迭代器的抽象层级更高)
# 所以, 拥有迭代器的特性
# 惰性计算数据, 节省内存
# 能够记录状态, 并通过next()函数, 访问下一个状态
# 具备可迭代特性
# 但是, 如果打造一个自己的迭代器, 比较复杂
# 需要实现很多方法
# 后续在"面向对象"编程中会进行讲解
# 所以, 就有一个更加优雅的方式 "生成器"
# 创建方式
# 生成器表达式
# 把列表推导式的[] 修改成 ()
# (i for i in range(1, 10000000) if i % 2 == 0)
# 生成器函数
# 函数中包含 yield语句
# 这个函数的执行结果就是 "生成器"
# 产生数据的方式
# 生成器具备可迭代特性
# next()函数
# 等价于
# 生成器.__next__()
# for in
# send() 方法
# send方法有一个参数,指定的是上一次被挂起的yield语句的返回值
# 相比于.__next__()
# 可以额外的给yield 语句 传值
# 注意第一次调用
# t.send(None)
# 关闭生成器
# g.close()
# 后续如果继续调用, 会抛出StopIteration异常提示
# 注意
# 如果碰到return
# 会直接终止, 抛出StopIteration异常提示
# 生成器只会遍历一次 # L = [i for i in range(1,100) if i % 2 == 0] #直接生成列表,range生成比较多的时候,浪费内存
L = (i for i in range(1, 100) if i % 2 == 0)
print(L) #<generator object <genexpr> at 0x03A7AC60>
print(next(L)) #
print(next(L)) #
print(L.__next__()) # for i in L:
print(i) # 从 8 开始,因为上面已经移动了指针 def test():
print("xxx")
yield 1
print("a") yield 2
print("b") runing = test() # 不会打印xxx
for i in runing:
print(i) # 递归函数
# 体现
# 函数A内部, 继续调用函数A
# 概念
# 传递
# 回归
# 注意事项
# 有传递, 一定要有回归
# 否则, 就是无限的循环调用
# 案例
# 求一个数值的阶乘 5!= 5 * 4 * 3 * 2 * 1 def jiecheng(n):
if n == 1:
return 1
return n * jiecheng(n - 1) print(jiecheng(5)) # # 函数作用域
# 基本概念
# 变量的作用域
# 变量的作用范围
# 可操作范围
# Python是静态作用域,也就是说在Python中,变量的作用域源于它在代码中的位置;
# 在不同的位置, 可能有不同的命名空间
# 命名空间
# 是作用域的体现形式
# 不同的具体的操作范围
# Python-LEGB
# L-Local
# 函数内的命名空间
# 作用范围: 当前整个函数体范围
# E-Enclosing function locals
# 外部嵌套函数的命名空间
# 作用范围: 闭包函数
# G-Global
# 全局命名空间
# 作用范围: 当前模块(文件)
# B-Builtin
# 内建模块命名空间
# 作用范围: 所有模块(文件)
# 注意
# Python中没有块级作用域
# 块级作用域
# 代码块中, 比如 if while for 后的代码块
# LEGB规则
# 按照L -> E -> G -> B 的顺序进行查找
# 基于命名空间的常见变量类型
# 局部变量
# 在一个函数内部定义的变量;
# 作用域为函数内部
# 查看局部变量
# locals()
# 全局变量
# 在函数外部, 文件最外层定义的变量
# 作用域为整个文件内部
# 查看全局变量
# globals()
# 注意点
# 访问原则
# 从内到外
# 结构规范
# 全局变量
# 函数定义
# 使用
# 修改
# 后续代码
# 全局变量和局部变量重名
# 获取
# 就近原则
# 修改
# global 全局变量
# 声明
# l -> e
# unlocal
# 命名
# 全局变量
# g_xxx
Python 函数定义和使用的更多相关文章
- Python(2)深入Python函数定义
Python学习 Part2:深入Python函数定义 在Python中,可以定义包含若干参数的函数,这里有几种可用的形式,也可以混合使用: 1. 默认参数 最常用的一种形式是为一个或多个参数指定默认 ...
- Python函数定义和使用
函数是一段可以重复多次调用的代码,通过输入的参数值,返回需要的结果.通过使用函数,可以提高代码的重复利用率.本文主要介绍Python函数的定义.调用和函数参数设置方法. 函数的定义 Python函数定 ...
- Python 函数定义以及参数传递
Python 函数定义以及参数传递1.函数定义#形如def func(args...): doSomething123以关键字def 开头,后面是函数名和参数下面是函数处理过程. 举例: def ad ...
- python函数定义
刚学用Python的时候,特别是看一些库的源码时,经常会看到func(*args, **kwargs)这样的函数定义,这个*和**让人有点费解.其实只要把函数参数定义搞清楚了,就不难理解了. 先说说函 ...
- Python学习-10.Python函数定义(二)
在Python中定义函数的时候,可以使用参数默认值的方式定义函数 例子: def welcome(who,state='is',action='talking'): print(who,state,a ...
- 9 - Python函数定义-位置参数-返回值
目录 1 函数介绍 1.1 为什么要使用函数 1.2 Python中的函数 2 函数的基本使用 3 函数的参数 3.1 参数的默认值 3.2 可变参数 3.2.1 可变位置传参 3.2.2 可变关键字 ...
- 初识python 函数(定义,传参,返回值)
python基础(二): 菜鸟教程基础知识讲解的非常全面,内容选择我认为的重点输出一遍 函数: 定义一个函数: 你可以定义一个由自己想要功能的函数,以下是简单的规则: def fun(arg): pa ...
- python 函数定义
我们可以创建一个函数来列出费氏数列 >>> def fib(n): # write Fibonacci series up to n ... """Pr ...
- Python学习 Part2:深入Python函数定义
在Python中,可以定义包含若干参数的函数,这里有几种可用的形式,也可以混合使用: 1. 默认参数 最常用的一种形式是为一个或多个参数指定默认值. >>> def ask_ok(p ...
随机推荐
- NSTimer的循环引用
在日常开发中想到会引起循环引用的一般比较容易想起的是 1.delegate 2.block 今天要说的就是另外一个,NSTimer 这个比较容易会被忽略掉 简单的说就是创建timer为成员变量的时候t ...
- Linux shell 1-初步认识
1.什么是linux linux是一种操作系统,它可划分为以下四部分 1.linux内核(Linux系统的核心,负责管理系统内存,硬件驱动,文件系统等) 2.GNU工具(一组软件工具,提供一些类UNI ...
- cxGrid 显示行号及行号列列名
cxGrid默认不显示行号,但是可以通过cxGrid1DBTableView1CustomDrawIndicatorCell事件来重绘行号 选中cxGrid1DBTableView1,在OnCusto ...
- Codeforces Round #364 (Div. 1)B. Connecting Universities
题目链接:传送门 题目大意:n个点构成一棵树,给定 k*2 点,要分成 k 组,使每组点之间的距离之和最大. 题目思路:因为是求距离之和最大,所以我们可以知道这样一个性质.如果以一条边为界,两边的子树 ...
- 【BZOJ3931】[CQOI2015]网络吞吐量 最大流
[BZOJ3931][CQOI2015]网络吞吐量 Description 路由是指通过计算机网络把信息从源地址传输到目的地址的活动,也是计算机网络设计中的重点和难点.网络中实现路由转发的硬件设备称为 ...
- 【BZOJ3996】[TJOI2015]线性代数 最大权闭合图
[BZOJ3996][TJOI2015]线性代数 Description 给出一个N*N的矩阵B和一个1*N的矩阵C.求出一个1*N的01矩阵A.使得 D=(A*B-C)*A^T最大.其中A^T为A的 ...
- [LintCode] A + B 问题
Bit-by-Bit summation: class Solution { public: /* * @param a: The first integer * @param b: The seco ...
- Powershell About Active Directory Group Membership of a domain user
使用Get-User命令去寻找group membership of a domain user $((Get-ADUser Wendy -Properties *).MemberOf -split ...
- centos7开机启动tomcat7
1.进入tomcat/bin vi setenv.sh (原来没有这个文件,需要创建出来) 添加 #add tomcat pid CATALINA_PID="$CATALINA_B ...
- MySQL中的datetime与timestamp比较(转载)
原文地址:http://database.51cto.com/art/200905/124240.htm 相同 显示 TIMESTAMP列的显示格式与DATETIME列相同.换句话说,显示宽度固定在1 ...