python函数编程

178 阅读15分钟

​本文已参与「新人创作礼」活动,一起开启掘金创作之路。

🌞欢迎来到python的世界
🌈博客主页:卿云阁

💌欢迎关注🎉点赞👍收藏⭐️留言📝

🌟本文由卿云阁原创!

🌠本阶段属于练气阶段,希望各位仙友顺利完成突破

📆首发时间:🌹2021年4月3日🌹

✉️希望可以和大家一起完成进阶之路!

🙏作者水平很有限,如果发现错误,请留言轰炸哦!万分感谢!

🍈 一、参数

(1)形参与实参

def calc(x,y):
    res = x**y
    print(res)

a = 5
b = 4

calc(a,b)

(2)默认参数

def zongce(name,mid,end,mid_rate=0.4):
    zongce=mid*mid_rate+end*(1-mid_rate)
    print("----学⽣信息------")
    print("期中成绩:", mid)
    print("期末成绩:", end)
    print("综测成绩:{0:<5}".format( zongce))
zongce("qingyun",98,99)
zongce("zhangxveqing",98,99,0.5)



结果
----学⽣信息------
期中成绩: 98
期末成绩: 99
综测成绩:98.6 
----学⽣信息------
期中成绩: 98
期末成绩: 99
综测成绩:98.5 

(3)可变参数

def sum(a,b,*c):
    print(c)
    total=a+b
    for i in c:
        total=total+i
    return total
print(sum(1,2,3,4,5,6,7))

结果
(3, 4, 5, 6, 7)
28

def sum(a,b,*c,**d):
    print(c)
    print(d)
    total=a+b
    for i in c:
        total=total+i
    for key in d:
        total=total+d[key]
    return total
print(sum(1,2,3,4,5,6,7,qingyun=1,zxq=2))
结果
(3, 4, 5, 6, 7)
{'qingyun': 1, 'zxq': 2}
31

🍉二. 返回值return

函数外部的代码要想获取函数的执⾏结果,就可以在函数⾥⽤return语句把结果返回

注意

函数在执⾏过程中只要遇到return语句,就会停⽌执⾏并返回结果,so 也可以理解为 return 语句 代表着函数的结束 如果未在函数中指定return,那这个函数的返回值为None

def zuowen(name,f,s,*o):
    max=f
    if f<s:
        max=s
    for i in o:
        if max<i:
            max=i
    print("----最终学⽣作文分数------")
    print("姓名:", name)
    print("作文分数:", max)
zuowen('qingyun',99,98,99,97,96,95)


结果
----最终学⽣作文分数------
姓名: qingyun
作文分数: 99

多条return语句

import math
def is_prime(n):
    if n<2: return False
    i=2
    while(i<math.sqrt(n)):
        if n%i==0:
           return False
        i+=1
    return True
for i in range(100):
    if is_prime(i):print(i,end=' ')
结果
2 3 4 5 7 9 11 13 17 19 23 25 29 31 37 41 43 47 49 53 59 61 67 71 73 79 83 89 97 

返回多个值

import random
def randomarry(n):
    a=[]
    for i in range(n):
        a.append(random.random())
    return a
b=randomarry(5)
print(b)
结果:
[0.6068501158240774, 0.0761204880150359, 0.8275832346568391, 0.3464213540970127, 0.8964706536915046]

🍊三,变量的作用域

name = "qingyun"
def change_name():
 name = "qingyunqingyunge"
 print("after change", name)
change_name()
print("now name",name)

传递列表、字典产⽣的现象

d = {"name":"qingyun","age":19,"hobbie":"pinpang"} 
l = ["Rebeeca","Katrina","Rachel"]
def change_data(info,girls):
 info["hobbie"] = "学习"
 girls.append("XiaoYun")
 
change_data(d,l)
print(d,l)

🍋四、内置函数

前面使用过一些函数,有的同学会疑问我没有导入这个函数,为什么可以直接使用?

因为这些函数都是一个叫做 builtins 模块中定义的函数,而 builtins 模块默认在Python环境启动的时 候就自动导入,所以你可以直接使用这些函数。

abs()

绝对值函数。如abs(-1)= 1

print(abs(-10))
f = abs 
print(f(-1))
abs=id 
print(abs(1))

以abs()函数为例,展示两个特性。一是,内置函数是可以被赋值给其他变量的,同样也可以将其他对象赋 值给内置函数,这时就完全变了。所以,内置函数不是Python关键字,要注意对它们的保护,不要使用和 内置函数重名的变量名,这会让代码混乱,容易发生难以排查的错误。

all()

接收一个可迭代对象,如果对象里的所有元素的bool运算值都是True,那么返回True,否则False

print(all([1,1,1]))

结果:
True

any()

接收一个可迭代对象,如果迭代对象里有一个元素的bool运算值是True,那么返回True,否则False。与all()是一 对兄弟。

print(any([0,0,1]))

结果
True

bin()、oct()、hex()

三个函数是将十进制数分别转换为2/8/16进制

i = 10 
print(bin(i))

结果
0b1010

zip()

组合对象。将对象逐一配对。

等等

🍐range函数

a = ['Google', 'Baidu', 'Huawei', 'Taobao', 'QQ']
for i in range(len(a)):
    print(i, a[i])
    
结果
0 Google
1 Baidu
2 Huawei
3 Taobao
4 QQ

🍑五、匿名函数

当我们在创建函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便。这省去了我们挖空心思为 函数命名的麻烦,也能少写不少代码,很多编程语言都提供这一特性。

Python语言使用 lambda 关键字来创建匿名函数。

所谓匿名,即不再使用 def 语句这样标准的形式定义一个函数。

1. lambda只是一个表达式,而不是一个代码块,函数体比def简单很多。

2. 仅仅能在lambda表达式中封装有限的逻辑。

3. lambda 函数拥有自己的命名空间

lambda x: x * x

它相当于下面的函数

def f(x): 
    return x*x 
关键字lambda表示匿名函数,冒号前面的x表示函数参数,x*x是执行代码

匿名函数只能有一个表达式,不用也不能写return语句,表达式的结果就是其返回值。 匿名函数没有函数名字, 不必担心函数名冲突,节省字义空间。此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量, 再利用变量来调用该函数.

f = lambda x: x * x
print(f(6))
#也可以把匿名函数作为别的函数的返回值返回 
def count(i,j): 
    return lambda : i*j
f = count(6,7) 
print(f)
print(f())

匿名函数的应用

对列表中的字典进行排序

lis = [1,-2,4,-3]
lis.sort(key=abs)
print(lis)
infors = [{'name':'cangls','age':18},{'name':'bols','age':20},{'name':'jtls','age':25}]
infors.sort(key = lambda x:x['name'])
print(infors)

匿名函数当做实参

def test(a,b,func): 
    result = func(a,b) 
    return result 
nums = test(11,22,lambda x,y:x+y) 
print(nums)

🍒六、推导式

Python语言有一种独特的推导式语法,相当于语法糖的存在,可以帮你在某些场合写出比较精简酷炫的代码。

列表推导式

lis = [x * x for x in range(1, 10)] 
print(lis)

字典推导式

dic = {i:i**3 for i in range(5)} 
print(dic)

集合推导式

s = {i for i in 'abasrdfsdfa' if i not in 'abc'} 
print(s)
#把abc排除剩余字符串

🥒七、迭代器

在介绍迭代器之前,先说明下迭代的概念:

迭代:通过for循环遍历对象的每一个元素的过程。

Python的for语法功能非常强大,可以遍历任何可迭代的对象。

在Python中, list/tuple/string/dict/set/bytes 都是可以迭代的数据类型。

可以通过collections模块的 Iterable 类型来判断一个对象是否可迭代:

from collections import Iterable 
isinstance('abc', Iterable) # str是否可迭代 
True 
isinstance([1,2,3], Iterable) # list是否可迭代 
True 
isinstance(123, Iterable) # 整数是否可迭代 
False

迭代器是一种可以被遍历的对象,并且能作用于next()函数。迭代器对象从集合的第一个元素开始访问,直到所 有的元素被访问完结束。 迭代器只能往后遍历不能回溯,不像列表,你随时可以取后面的数据,也可以返回头取 前面的数据。迭代器通常要实现两个基本的方法: iter() 和 next() 。 字符串,列表或元组对象,甚至自定义对象都可用于创建迭代器:

from collections.abc import Iterable,Iterator
print(isinstance([],Iterable)) #是否可迭代
print(isinstance([],Iterator)) #是否是迭代器
lis=[1,2,3,4]
it = iter(lis) # 使用Python内置的iter()方法创建迭代器对象
print(next(it)) # 使用next()方法获取迭代器的下一个元素
print(next(it)) # 使用next()方法获取迭代器的下一个元素
print(next(it)) # 使用next()方法获取迭代器的下一个元素
print(next(it))# 使用next()方法获取迭代器的下一个元素

结果
True
False
1
2
3
4

Python的迭代器表示的是一个元素流,可以被next()函数调用并不断返回下一个元素,直到没有元素时抛 出StopIteration错误。可以把这个元素流看做是一个有序序列,但却不能提前知道序列的长度,只能不断通过 next()函数得到下一个元素,所以迭代器可以节省内存和空间。 迭代器(Iterator)和可迭代(Iterable)的区别:

1. 凡是可作用于for循环的对象都是可迭代类型;

2. 凡是可作用于next()函数的对象都是迭代器类型;

3. list、dict、str等是可迭代的但不是迭代器,因为next()函数无法调用它们。可以通过iter()函数将它们转换成 迭代器。

4. Python的for循环本质上就是通过不断调用next()函数实现的。

🥬八、生成器

有时候,序列或集合内的元素的个数非常巨大,如果全制造出来并放入内存,对计算机的压力是非常大的。比 如,假设需要获取一个10**20次方如此巨大的数据序列,把每一个数都生成出来,并放在一个内存的列表内,这 是粗暴的方式,有如此大的内存么?如果元素可以按照某种算法推算出来,需要就计算到哪个,就可以在循环的 过程中不断推算出后续的元素,而不必创建完整的元素集合,从而节省大量的空间。在Python中,这种一边循环

一边计算出元素的机制,称为生成器:generator。

生成生成器:

g = (x * x for x in range(1, 4))
print(g)

可以通过next()获得generator的下一个返回值,这点和迭代器非常相似:

g = (x * x for x in range(1, 4))
print(g)
print(next(g))
print(next(g))

结果:
1
4

除了使用生成器推导式,我们还可以使用 yield 关键字。

def createNums():
     print("----func start------")
     a,b = 0,1
     for i in range(5):
         print(b)
         print("--1--")
         yield b
         print("--2--")
         a,b = b,a+b # a,b = 1, 1 a,b = 1,2
         print("--3--")
         print("----func end------")
g= createNums()
print(next(g)) # 如果想得到yield的值,可以打印next(g)
print(next(g)) 
结果
----func start------
1
--1--
1
--2--
--3--
----func end------
1
--1--
1

在 Python中,使用yield返回的函数会变成一个生成器(generator)。 在调用生成器的过程中,每次遇到yield 时函数会暂停并保存当前所有的运行信息,返回yield的值。并在下一次执行next()方法时从当前位置继续运行。

生成器的应用

实现多任务

def test1():
     while True:
          print("--1--")
          yield None
def test2():
     while True:
          print("--2--")
          yield None
t1 = test1()
t2 = test2()
while True:
     next(t1)
     next(t2)
     break
结果
--1--
--2--

🥦九、装饰器

装饰器(Decorator):从字面上理解,就是装饰对象的器件。可以在不修改原有代码的情况下,为被装饰的对 象增加新的功能或者附加限制条件或者帮助输出。装饰器有很多种,有函数的装饰器,也有类的装饰器。装饰器 在很多语言中的名字也不尽相同,它体现的是设计模式中的装饰模式,强调的是开放封闭原则。装饰器的语法是 将@装饰器名,放在被装饰对象上面。

@dec 
def func(): 
   pass

在介绍装饰器之前,先要了解几个知识点

重名函数会怎么样?

def test():
     print('1')
def test():
     print('2')
test() #这个时候会输出什么? 会输出2,后面的会覆盖前面的函数 

接下来就是一个比较经典的案例了,有一个大公司,下属的基础平台部负责内部应用程序及API的开发。另外还 有上百个业务部门负责不同的业务,这些业务部门各自调用基础平台部提供的不同函数,也就是API处理自己的

业务,情况如下:

基础平台部门提供的功能如下

def f1(): 
    print("业务部门1的数据接口......") 
def f2(): 
    print("业务部门2的数据接口......") 
def f3(): 
    print("业务部门3的数据接口......") 
def f100(): 
    print("业务部门100的数据接口......") 
#各部门分别调用基础平台提供的功能 
f1() 
f2() 
f3() 
f100()

目前公司发展壮大,但是以前没有考虑到验证相关的问题,即:基础平台提供的功能可以被任何人使用。现在需 要对基础平台的所有功能进行重构,为平台提供的功能添加验证机制,执行功能前,先进行验证 老大把工作交给 A,他是这么做的: 跟每个业务部门交涉,每个业务部门自己写代码,调用基础平台的功能之前先验证。这样一

来基础平台就不需要做任何修改了。 当前A被老大开除了 老大又把工作交给B,他是这么做的:

def f1(): 
# 验证1 
# 验证2 
# 验证3 
def f2(): 
# 验证1 
# 验证2 
# 验证3 
过了一周B也被开除了。。。。。。。。。。

老大又把工作交给C,他是这么做的:

def check_login() 
# 验证1
 # 验证2
 # 验证3 
def f1(): 
    check_login() 
def f2(): 
    check_login()

老大说写代码要遵循开放封闭的原则,虽然在这个原则是用的面向对象开发,但是也适用于函数式编程,简单来

说,已经实现的功能不允许修改,但可以被扩展 。

封闭:已实现的功能代码块

开放:对扩展开发

老大给出了方案, 
def foo(): 
    def inner(): 
        验证1 
        验证2 
        验证3 
        result = func() 
        return result
return inner 

@foo 
def f1(): 
    pass
@foo
def f2(): 
    pass

看不懂?没关系,接下来写一个简单点的

def w1(func):
     def inner():
          print('正在验证权限')
          func()
     return inner
def f1():
     print('f1')

innerFunc = w1(f1) # innerFunc = inner
innerFunc() # inner()
f1 = w1(f1)
f1()
def outer(func):
     def inner():
          print("认证成功!")
          result = func()
          print("日志添加成功")
     return inner
@outer # f1 = outer(f1) = inner
def f1():
     print("业务部门1数据接口......")
f1()

结果:
正在验证权限
f1
正在验证权限
f1
认证成功!
业务部门1数据接口......
日志添加成功
1 程序开始运行,从上往下解释,读到def outer(func):的时候,发现这是个“一等公民”函数,于是把 函数体加载到内存里,然后过。
 2 读到@outer的时候,程序被@这个语法糖吸引住了,知道这是个装饰器,按规矩要立即执行的,于是程序 开始运行@后面那个名字outer所定义的函数。
 3 程序返回到outer函数,开始执行装饰器的语法规则。 规则是:被装饰的函数的名字会被当作参数传递给装饰函数。装饰函数执行它自己内部的代码后,会将它的 返回值赋值给被装饰的函数。原来的f1函数被当做参数传递给了func,而f1这个函数名之后会指向inner 函数