python - 函数

目录

函数的定义与调用

# 匿名函数 -lambda

# 递归函数

函数的参数传递

# 变量的作用域

# 变量名的解析(LEGB)

# 文档注释 (Document String)

# 内建函数和工厂函数


函数的定义与调用

1.什么是函数

在数学·里面·函数是一个表达式的集合

例如 : f(x) = x +10

在开发语言里面:

函数是指具体实现某一功能的代码

函数定义:用关键字def

def add(a, b):
    print("exac add function")
    return a + b


print(add(1, 2))
result = add(3, 4)
print(result)

#为什么要写函数:

#1.方便维护,模块化设计

以上代码为例,如果没有封装add函数,那么当代码出错的·时候我们需要到两个地方进行排查,但是封装函数以后,我们只需要检查add函数。

#2.减少代码的冗余

#函数的参数

1.形参:形式参数,函数定义时,指定的参数。

以上面的add函数为例:形参就是 add(a,b)

2.实参:实际线束,函数调用的术后,传递的参数。

以上面的add函数为例,实参就是 add(1,2)

#按形参来分:

1.必选参数

2.默认参数

3.可变长位置参数

4.可变长关键字参数

#按实参来分

1.位置参数

2.关键字参数

# 必选参数
def stuinfo(name, age, sex):
    print(f"myname is {name}, myage is {age}, mysex is {sex}")
# 有几个必选参数就要传入几个参数。参数的位置是一一对应的
# 少传或者多传会报错。
stuinfo("sc", 4, 'man')
# 默认参数
def stuinfo(name, age, sex='man'):
    print(f"myname is {name}, myage is {age}, mysex is {sex}")


stuinfo("sc", 21)
stuinfo("sc", 21, 'women')
# 关键字参数
stuinfo("sc", sex='man', age=6)
# 位置参数一定要放在关键字参数的前面。
#注意定义顺序,默认参数放在必须参数前面
#注意调用顺序,关键字参数必须放在位置参数的后面
# 可变长位置参数
def myargs(name, *num):
    print(f"{name}:{num}")
    print(type(num), *num)


myargs("sc")
myargs("sc1", 1)
myargs("sc2", 1, 2)
# packing and  unpacking
# packing
# 1,2-->打包为元组(1,2)
# *num
# unpacking --》{"a":1,"b":2} --》a=1,b=2
# (1,2)--》1,2
# 可变长位置参数   --》 传进来的参数打包成元组。
def sum1(*args):
    sum0 = 0
    for i in args:
        sum0 += i
    print(f"可变长位置参数的和为{sum0}")

# 可变长关键字参数  --》 穿进来的参数打包成字典。

#
def sum2(**kwargs):
    sum3 = 0
    for i, j in kwargs.items():
        sum3 += j
    print(f"可变长关键字参数和为:{sum3}")


sum1(1, 2, 3, 4, 5, 6, 7)
sum2(a=1, b=2, c=3, d=4)

# 形参定义顺序

# func01(必选参数,可变长位置参数,默认参数,可变长关键字参数。)

# 实参

# func01(位置参数,关键字参数)

#函数的return语句

#一个函数一旦执行到return就退出,不会执行后面的语句

#如果函数没有return,默认返回None,

#如果return后面不接表达式,返回值也是None。

#return 一次也可以返回多个值。

def maxnum(x, y):
    print("return 语句:...")
    if x > y:
        print("return x")
        return x
    elif x < y:
        print("return y")
        return y
    else:
        print("return end ..")
        return x, y


result = maxnum(8, 8)
print(f"结果为:{result}")

# 匿名函数 -lambda

匿名函数及其表达式

匿名函数在创建时不需要命名,所以叫匿名函数

匿名函数有个限制,就是只能有一个表达式,不用写retutrn

返回值就是改函数的值

 

# 使用匿名函数来返回两个数之间的最大值
maxnum = lambda a, b: max(a, b)
maxnum1 = lambda a, b: a if a > b else b
maxnum2 = lambda a, b: a > b and a or b
print(maxnum(100, 200))
print(maxnum1(100, 800))
print(maxnum2(100, 2800))
# 使用匿名函数,将传入的浮点数保留两位小数
# round  将一个数保留几位小数输出成一个浮点数
floatnum = lambda x: round(x, 2)
floatnum1 = lambda  x: float('%.2f'%x)
print(floatnum(2.168454))
print(floatnum1(2.168454))
E:\python\python3.9.1\python.exe E:/tlbb/python函数/匿名函数和递归函数.py
200
800
2800
2.17
2.17

# 递归函数

# 自己调用自己,形成循环

# 定义出口条件,什么时候结束递归

# 通常是把一个大问题通过寻找规律可以缩小规模时候使用

# 不能无限制的递归,最大深度996

#递归是非常耗内存的,它会把每一次的中间结果保存在内存中,直到找到出口

#能不用递归尽量不用递归,因为它计算量大,耗内存,效率低

例:

求取n的阶乘

f(n)=1*2*3*..*n

f(n)=n*f(n-1)

# 求取 n 的阶乘、
# f(n)=1*2*3*....*n
# 最大递归深度 996
def func01(n):
    if n == 1:
        return 1
    return n * func01(n-1)


print(func01(5))

E:\python\python3.9.1\python.exe E:/tlbb/python函数/匿名函数和递归函数.py
120

Process finished with exit code 0

使用递归求取斐波拉契数列

# 1,1,2,3,5,8,13,21

# 使用递归实现斐波拉契数列
# 1,1,2,3,5,8,13
def fblq(n):
    if n == 1 or n ==2:
        return 1
    else:
        return fblq(n-1)+fblq(n-2)


num = int(input("请输入一个数:"))
for i in range(1, num+1):
    print(fblq(i), end=',')
    
E:\python\python3.9.1\python.exe E:/tlbb/python函数/匿名函数和递归函数.py
请输入一个数:8
1,1,2,3,5,8,13,21,
Process finished with exit code 0

雌雄兔子的繁殖问题

有一对雌雄兔子,没两个月就繁殖雌雄兔一对,问n个月后有多少对兔子

f(n)=f(n-2)*2

def rabbits(n):
    if n == 1 or n == 2:
        return 1
    else:
        return rabbits(n-2) * 2
print(rabbits(6))

E:\python\python3.9.1\python.exe E:/tlbb/python函数/匿名函数和递归函数.py
4

Process finished with exit code 0

函数的参数传递

本质上面都是传递引用

全局变量和局部变量

函数的参数传递本质上面都是传递引用
变量的空间作用域

def func1(x):
    print(x)
#   定义在函数内部的称为局部变量
    x = 100
# 改变局部变量的值全局变量的值不会变
    print(x)


# 全局变量
x = 1

但是对于可变数据类型来说,改变它的值全局变量也会改变

例如,对一个可变数据类型 : 列表来说;

# 可变数据类型
def f(x):
    x[0] = 100
    print(x)


a = [1, 2, 3]
f(a)
print(a)

E:\python\python3.9.1\python.exe E:/tlbb/python函数/03.函数的参数传递.py
[100, 2, 3]
[100, 2, 3]

Process finished with exit code 0

# 参数定义的时候。默认参数避免定义成可变数据类型

例如:

可以看到,我们列表a因为是一个可变数据类型,所以每一次追加

1的时候,a也会变,所以就不是我们刚定义时候的空列表了

# 参数定义的时候,默认参数避免定义成一个可变数据类型
def f(a=[]):
    a.append(1)
    print(a)


f()
f()
f()

E:\python\python3.9.1\python.exe E:/tlbb/python函数/03.函数的参数传递.py
[1]
[1, 1]
[1, 1, 1]

Process finished with exit code 0

# 变量的作用域

如果要声明一个变量为全局变量,就不要在前面再定义一个同名的局部变量,因为会产生混淆,会报错。

# 在局部变量里面修改全局变量的值
def f():
    global x  #申明x为全局变量
    x = 5


x = 1
f()
print(x)

E:\python\python3.9.1\python.exe E:/tlbb/python函数/03.函数的参数传递.py
5

Process finished with exit code 0

# 变量名的解析(LEGB)

1.在本地变量中·找 --》local

2.在任意上层函数中找 --》 enclosing

3.在全局变量中找 --》 global

4.在内置作用域找 --》 builtin

以双下滑线和双下滑线结尾的变量都是内置变量

例如 : 当前输出 : 3

def f():
    x = 2
    def f2():
        x = 3
        print(x)
    f2()


x = 1
f()
E:\python\python3.9.1\python.exe E:/tlbb/python函数/03.函数的参数传递.py
3

Process finished with exit code 0

将x = 3注释掉以后:

输出 : 2

E:\python\python3.9.1\python.exe E:/tlbb/python函数/03.函数的参数传递.py

2

Process finished with exit code 0

将x = 2注释掉以后:输出: 1

E:\python\python3.9.1\python.exe E:/tlbb/python函数/03.函数的参数传递.py

1

Process finished with exit code 0

# 文档注释 (Document String)

不管什么时候,注释是很重要的,

def f():
    """
    this is test func
    :return:
    """
    print("hello")

print(help(f))

E:\python\python3.9.1\python.exe E:/tlbb/python函数/03.函数的参数传递.py
Help on function f in module __main__:

f()
    this is test func
    :return:

None

Process finished with exit code 0

# 内建函数和工厂函数

内建函数:

python 里面已经建好的,我们无需导入,直接调用就好

内建方法:

一般是针对面向对象而言,是类的方法。

内建方法就是指一个自带的对象所带的方法,例如list的pop方法

工厂函数:

所谓工厂函数就是指这些内建函数都是类对象

他们看上去像函数,实质上他们是类

当你调用他们的时,实际上是生成了该类型的一个实例,就像工 厂生产货物一样。

工厂函数主要与数据类型相关

int(),float(),complex(),bool()

str(),

list(),tuple()。生成列表或者元组

dict(),set(),生成一个字典或者集合。

slice()

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值