Python函数与装饰器入门一

Posted buono

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python函数与装饰器入门一相关的知识,希望对你有一定的参考价值。

语句简写

三元运算(三目运算)

解决if,else条件的简写。

v = A if 条件  else B  
# 如果条件为真,就把A赋值给V,否则赋值B

lambda表达式

简单函数的简写

def func(a1,a2):
    return a1+a2   #这种简单返回数值的函数形式,可以简化为:

func = lambda a1,a2:a1+a2   #这种简便写法叫做lambda表达式,和上面的形式没有区别

两者可以相互结合,实现简写

func = lambda a1,a2: a1 if a1>0 else a2  #函数根据不同的条件输出不同的值

函数

定义

之前简单的代码实现都是面向过程编程,实现一次就需要写一次,可读性非常差。

通过函数可以实现面向对象编程。 简单来说把一段代码取名,以后直接用名字来调用这一段代码,并且可以动态更改这段代码里面的参数。提高可读性

基本结构

#定义函数
def 函数名(设定的形式参数):
    #函数内容
    
#执行函数
函数名(输入变量的实际参数)

函数的返回值

执行完函数后,可以指定返回一些参数

def haoran(a):
    a += 1
    return a #返回值,不写返回None,返回数字、元组、字典等都可以

val_a = haoran(22) #执行函数后把return值赋给val_a

函数执行过程中,一旦遇到return,就不再继续执行了

文件操作的补充

打开文件,关闭文件的操作容易忘记,可以直接写

with open("/tmp/foo.txt") as file:
    data = file.read()
#这样就不用f.close操作了

函数参数(arguments)

1.位置参数: 按照顺序来传参数,那少传,多传都会报错。

def func(a1,a2):
    print(a1,a2)
func(22,99)

2.关键字传参数:

def func(a1,a2):
    print(a1,a2)
func(a1=22,a2=99)

以上两者可以混合使用,位置前,关键字参数在后

3.默认参数

def func(a1,a2=9): #a2不传就等于9, 传就按输入的来
    print(a1,a2)
func(a1=22,a2=99)

4.万能参数

def func(*a1): #带*, 默认会写成*args(arguments的缩写)
    print(a1)
func(1,232,534534) #把所有参数传给a1,成为一个元组
func(*(1,2,3,4))  #加*就打散所有元素加进去,否则只分开最外层

带*的参数只能用位置传参

带**的情况

def func(**kwargs):#**情况一般写kwargs
    print(kwargs)
func(k1 = 1, k2 = 'ran')  
#输出:{'k1': 1, 'k2': 'ran'} ,为字典

作用域

整个代码环境从上到下执行的地方,叫做全局作用域。

函数没有执行的时候那几行代码实际是跳过的,这就叫局部作用域。 只有在你调用这个函数的时候,这几行代码才开始从上到下执行。 作用域中的数据归自己所有,别人访问不到。 只有最后会返回一个值到全局中去。

作用域中引用数据规则:优先在自己的作用域找,自己的找不到就去父级, 直到全局作用域,全局都没有就报错。

作用到全局的方法

global 可以作用到全局

name = 'ran'
def func():
    global name  #这下就把“hao” 给赋到全局变量里面了,不然只有在函数作用域里name = hao
    name = "hao"
func()

nonlocal 函数以此类推,只赋到上一级变量

书写规范

以后写全局变量名字必须大写,局部变量可大可小写

函数高级

函数的赋值

函数也可以和变量一样进行赋值

def func():
    print(1)
v1 = func 
v1() #这样也可以用函数

以此内推,函数名也可以进行调用,例如嵌入到列表里

def func():
    print(1)
V_list = [func,func2]  #这个列表里有两个函数, 可以根据需要进行调用,调用后加括号即可执行

同样,函数可以当作字典的value,但是一般不当key

闭包

为函数创建一块区域为其维护自己数据,以后执行时方便调用

def outer(x):
    def inner(y):
        return x + y
    return inner 

inner(y)就是这个内部函数,对在外部作用域(但不是在全局作用域)的变量进行引用:x就是被引用的变量,x在外部作用域outer里面,但不在全局作用域里,则这个内部函数inner就是一个闭包

装饰器

装饰器的作用是在原函数的基础上添加功能,但是不破坏原函数的结构。 做法是包上一层。

def wrapper(func):
    def inner():
        # 想在原函数基础上增加打印“登录” 这个功能
        print("登录")
        func()  #原函数f1被当作参数传到func中了,所以此处就是运行原函数
        return func()  #装饰器结束,返回和原函数一样的值

    return inner


@wrapper  # f1 = wrapper(f1)的简写(也叫语法糖) , 这样func=f1函数,f1又重新定义为inner函数了
#@www(9) 这种情况,先计算函数的返回值,随后必须得到的是一个函数名,然后再同理上面一步
def f1():
    # 这是基本的函数,实现打印123
    print(1)


f1()

这样可以保证调用接口还是f1(),新增了功能。 返回值不变

如此看最外层wrapper好像多此一举,好像只需内层函数就满足了新增功能的需求。 其实外层函数的作用是让这个嵌套不执行,保持和原来一样的启动方式。

万能参数

如果不加入万能参数,装饰器就不能同时应对存在不同数量参数这种情况。

def wrapper(func):
    def inner(*args,**kwargs): #这样完美解决,想传啥就传啥~
        print("登录")
        func(*args,**kwargs)  
        return func()  

    return inner

装饰器的推导

列表推导式

val = [i for i in "ran"] #循环ran的字符,每循环一个,就加入到val这个列表中
val = [100 for i in "ran"] #每循环一次,就添加“100”到列表中
val = [func for i in "ran"] #每循环一次,还可以添加函数到列表里,但是不会执行

注意:

在列表里面生成了10个函数,但是这些函数并没有执行,所以不会给i赋值。 因此列表中的10个函数的i都是一样的。 我们从列表中取任意函数来运行,返回值i都只能读取到 for循环结束的时候i的值9

def func:
    return i 
v8 = [func for i in range(10)]
print(v8[0]()) #无论取哪个函数,i的值都是循环结束时的9,之前循环0-8时,函数没有执行,所以也没存储0-8

字典,集合的推导式以此类推

time 模块

import time
v = time.time() #获取当前时间,从0时区的1970年开始以秒为单位
time.sleep(5)  #运行至此行停顿5秒

递归

函数自己调用自己,尽量不要用递归,因为效率低,内存一直在用。 最好用while循环代替。

用递归来计算斐波那契数列

斐波那契数列: 从第三项开始,每一项都等于前2项之和。 1、1、2、3、5、

def func(a, b):
    print(b)
    func(b, a + b)


func(0, 1)

带参数的装饰器

相当于把装饰器再包裹一层,这样可以获得一个可以随时调用的变量、

  def x(counter):
    def wrapper(func):
        def inner(*args,**kwargs): 
            print("登录")
            func(*args,**kwargs)  
            return func()  
        return inner
    return wrapper

@x(9)#可以传参数
def f1():
    pass

以上是关于Python函数与装饰器入门一的主要内容,如果未能解决你的问题,请参考以下文章

Python入门篇之装饰器

Python入门之函数的装饰器

Python入门自学进阶——1--装饰器

Python入门之python装饰器的4种类型:函数装饰函数函数装饰类类装饰函数类装饰类

python入门基础-函数装饰器的理解

python入门之装饰器