Python函数
函数定义
def 函数名(参数列表):
["注释块"](可选)
语句块(代码块)
return [返回值](可选)
函数本身也是一个变量,该变量类型就是可调用类型,属性只读。
参数列表和返回值都可以是多个,用逗号隔开。
函数的参数传递
传递方式:
- 位置传参:实际参数的对应关系与形式参数的对应关系以位置一次确定。
- 位置必须对应,个数必须完全相同
- 关键字传参:传参时按照形参的名称给形参赋值。sum(a=1, b=2, c=3)
- 位置可以乱序,个数必须相同。
-
- 序列传参
序列类型(list, tuple, str)作为参数列表传递。要求序列的元素个数必须与参数的个数相同。
- 序列传参
s1 = [11,22,33]
sum(*s1) # 相当于sum(s1[0],s1[1],s1[2])
- ** 字典关键字传参:实参和形参通过字典进行传递和匹配,字典的值传递给键对应的形参
dict1 = {"a":11, "c": 33, "b": 22}
sum(**dict)
字典传参键名和形参名必须一致;
键名必须为字符串;
键名药在形参中存在。
5. 综合传参:以上几种的混合使用
函数的缺省参数
已经定义默认参数值的形参,在调用时如果没有实参进行值传递,则使用默认值计算。
def 函数名(形参1=默认参数值1, 形参2=默认参数值2, ...):
缺省参数说明:
- 缺省参数必须自作至右依次存在,如果一个参数有缺省值,则其右侧的所有参数都必须有缺省参数
- 缺省参数可以有0个或多个,甚至全部都有缺省参数
函数的不定长参数
不定长参数有两种:1. 星号元组形参;2. 双星号字典形参
星号元组形参
def 函数名(*元组形参名):
语句块
def sum(*args)
print('实参个数是:', len(args))
for x in args:
print(x)
命名关键字形参
def 函数名(*, 命名关键字形参名):
语句块
def 函数名(*args, 命名关键字形参名):
语句块
def sum(a, b, *, c)
print(a, b, c)
sum(1, 2, c=3) #正确使用方法
sun(1, 2, 3) # 报错
sum(a1, c=3, b=2) # 可以
双星号字典形参
def sum(**kwargs):
print("number of vars:", len(kwargs))
sum(name="abc", age=15)
sum(a=1, b="123", c=[1,2,3], d=True
sum(1,2,3) # 错误,没有给键名
函数的参数列表顺序
- 位置形参,缺省形参,星号元组形参,双星号字典形参,命名关键字参数可以混合使用。
- 函数参数自左至右的顺序为:位置形参,星号元组形参,命名关键词参数,双星号字典形参,默认
例子:
def fn(a, b, *args, c, **kwargs):
pass
fn(100,200,300,400,c="C", d="D", e="E")
# a=100, b=200, args=(300,400), c="C", kwargs={"d"="D","e"="E"}
详细语法可以在Python中看帮助,>>> help("def")
可变/不可变类型
可变类型:列表list,集合set,字典dict
不可变类型:frozenset, tuple, str, numbers
L = []
def fn(x):
x.append(10)
fn(L) # L =[10]
fn(L) # L = [10,10]
X = 100
def fn(x)
x = 200
fn(X) # X =100, 不变。
作用域:全局变量和局部变量
python作用域4个分类:
- L - Local:局部作用域(函数内)
- E - Enclosing Function Locals:外部嵌套函数作用域
- G - Global(Module):函数定义所在模块(文件)的作用域
- B - Built-In:Python内置模块的作用域
"""
变量作用域演示代码
"""
v =100 # 全局作用域 G
def fun1():
v =200 # 相对fun2的外部嵌套函数作用域 E(嵌套函数的夹层中定义的变量)
print("fun1.v = ", v)
def fun2():
v=300 # 局部作用域 L
print("fun2.v = ", v)
fun2()
fun1()
print("v=", v)
print(__doc__) # __doc__是内建作用域的变量
变量名的查找顺序:
局部L => 外部函数E =》全局G =》 内建B
函数内声明全局变量:global
v = 100
def fn1():
global v # 声明全局变量v
v =200 # 修改全局变量v
def fn2(v):
global v # 报错,v在参数列表中。
函数嵌套
函数嵌套:一个函数里用def语句来创建其他函数的情况。
nonlocal语句:声明的变量不是局部变量,也不是全局变量,而是外部嵌套函数内的变量。(与global类似,global是声明全局变量)
更好的方法,global变量用
g_变量名
,外部嵌套变量用e_变量名
。
globals() # 返回所有全局变量
locals() # 返回所有局部变量
函数式编程思想
函数式编程是指用一系列函数解决问题。函数仅接受输入并产生输出,不包含任何影响产生输出的内部状态。在任何情况下,使用相同的参数调用函数始终能产生同样的结果。
有边界效应的函数:不可重入的函数。使用了全局变量,静态变量,或者处理的数据部全是来自函数的输入(比如来自硬件)的。使得同样的输入可能会产生不同的输出。
纯函数式:可重入的函数。类似数学的函数映射,给定输入,就会得到指定的输出,没有任何副作用。
函数式编程的优点:逻辑可证、模块化、组件化、易于调试、易于测试、更高的生产率
函数式编程的基础风格特征
函数是一等公民,函数能作为参数传递,也可以作为返回值返回。
函数变量:函数名是变量,它在创建函数时绑定一个函数对象。
def fn():
print("hello world")
f1 = fn
fn() # 等于调用函数fn()
高阶函数:High Order Function
满足以下条件中的一个的函数,即为高阶函数:
- 函数接受一个或多个函数作为参数传入
- 函数返回一个函数
偏函数
函数有很多参数时,如果固定住一些参数,可以利用functools模块Partial得到一个偏函数,方便以后的使用。
>>> int('12345')
12345
>>> int('12345', base=8)
5349
# 偏函数设定
>>> import functools
>>> int8 = functools.partial(int, base=8)
>>> int8('12345')
5349
>>>
Python中内置(built in)的高阶函数
map函数
map(func, *iterable) 用func和可迭代对象iterable中的每个元素作为参数计算出新的可迭代对象,当最短的一个可迭代对象完成迭代后,此迭代生成结束。
def power2(x):
return x ** 2
mit = map(power2, range(1,10))
for x in mit:
print(x)
# 输出为1-9的平方
reduce函数
reduce(function, iterable[, initializer])
对参数序列中元素进行累积。
def add(x, y):
return x+y
reduce(add, [1,2,3,4,5]) # 计算过程为:1+2 = 3, 3+3=6, 6+4=10, 10+5=15
15
filter函数
filter(function or None, iterable)
def is_odd(n):
return n%2 ==1
newlist = filter(is_odd, [1,2,3,4,5,6,7,8,9,10])
print(newlist) # [1,3,5,7,9]
sorted函数
将原可迭代对象的数据进行排序,生成排序后的列表。
sorted(iterable, key=None, reverse = False) # key是排序的关键词。
L = [5, -2, -4, 0, 3, 1]
L2 = sorted(L) # [-4, -2, 0, 3, 5]
L2 = sorted(L, reverse=True) # [5,3,1,-2,-4]
L2 = sorted(L, key=abs) # 按照绝对值排序[0, 1, -2, 3, -4, 5]
names = ['Tom', 'Jerry', 'Spike', 'Tyke']
sorted(names)
sorted(names, key=len)
Lambda表达式(匿名函数)
lambda [参数1,参数2,...] : 表达式
同def类似,但不提供函数名
def myadd(x, y):
return x+y
# 可以写成
myadd = lambda x, y : x+y
内置不可变数据结构
递归函数
递归是一种取代循环的方法。函数直接或间接地调用自己。
用递归做树状结构(不知道多少层)的遍历,比循环要好。
闭包
将组成函数的语句和这些语句的执行环境打包在一起时,得到的对象成为闭包。
如果一个内嵌函数访问函数外部作用域的变量,则这个函数就是闭包。
def make_power(x):
def fn(arg):
return arg ** x
return fn
f2 = make_power(2)
y = f2(100) # 10000
f3 = make_power(3)
f3(3) # 27
f4= make_power(4)
f4(2) # 16
make_power(4)(2) # 16
装饰器 decorator
装饰器是一个函数,主要作用是用来包装另一个函数或类。
包装的目的是在不改变函数名的情况下,改变被包装函数(对象)的行为。
def deco(fn):
def myfunc2():
print("装饰器函数被调用,并返回原函数")
fn()
return myfunc2
@deco
def myfunc():
print("函数myfunc被调用")
# 装饰器相当于执行myfunc = deco(myfunc)
myfunc()
被装饰函数带有参数的装饰器
def msg_service(fn):
def savemoney2(name, x):
print("欢迎", name, "来办理业务!")
fn(name, x)
print(name, "存入了", x, "元,短信发送中...")
return savemoney2
@msg_service
def savemoney(name, x):
print(name, "存钱", x, "元")
savemoney("张三",100)
被装饰函数带有不定参数的装饰器
def deco(func):
def _deco(*args, **kwargs):
print("before %s called." % func.__name__)
ret = func(*args, **kwargs)
print("after %s called. result: %s" % (func.__name__, ret))
return ret
return _deco
@deco
def myfunc(a,b):
print("myfunc(%s, %s) called." % (a, b))
return a+b
@deco
def myfunc2(a,b,c):
print("myfunc2(%s,%s,%s) called." % (a,b,c))
return a+b+c
带参数的装饰器函数语法
@装饰器函数名[(装饰器函数传参)]
def 函数名(参数列表):
语句块
def deco(arg):
def _deco(func):
def __deco():
print("before %s called [%s]." % (func.__name__, arg))
func()
print("after %s called [%s]." % (func.__name__, arg))
return __deco
return _deco
@deco("mymodule")
def myfunc():
print("myfunc() called.")
函数的属性
name 属性:函数名
doc 属性:记录文档字符,函数的第一行的注释看为函数的文档。
模块
模块是一个包含有一系列变量,函数,类等组成的程序组。
模块是一个文件,模块文件通常以.py为后缀。
作用:
让一些相关的变量,函数,类等有逻辑地组织在一起,让逻辑机构更加清晰。
模块中的变量,函数和类等可以供其他模块或程序使用
import 模块名1 [as 模块新名1], 模块名2, ...
from 模块名 import 模块属性名1 as 模块属性新名1, 模块属性名2, ...
help(obj) 查看模块相关的文档字符串
dir(obj) 返回模块所有属性的字符串列表
模块的属性:
name 属性:模块的名字
doc 属性:用来绑定模块的文档字符串(首行注释)
all 属性:可导出属性的列表
file 属性:模块对应的文件路径名
模块的隐藏属性:
模块中以"_"或""开头,不以""结尾的属性,在from import * 语句导入中,将不被导入到其他模块
包(模块包) Package
包是将模块一文件夹的组织形式进行分组管理的方法
包的作用:
将一系列模块进行分类管理,有利于防止名字冲突。
可以在需要加载一个或部分模块,而不是全部模块。
包的加载
import 包名 [as 包别名]
import 包名.模块名 [as 模块别名]
import 包名.子包名.模块名 [as 模块别名]
from import 类似
init.py : 表示此文件夹是包。作用:
- 在内部填写包的文档字符串。
- 加载此包所依赖的一些模块或其他包。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律