学习python笔记 ---->函数-装饰器

225 阅读4分钟

调用函数

def 函数名(参数列表):
    return 函数体

例子

def my_abs(x):
    if x >= 100:
        return x
    else:
        return -x
print(my_abs(10))

函数的参数

默认参数

def add_end(L=[]):
    L.append('END')
    return L
print(add_end())#['END']
print(add_end())#['END','END']
print(add_end())#['END', 'END', 'END']
print(add_end([1,2,3,4]))#[1, 2, 3, 4, 'END']

为什么会这样呢? 因为在定义这个函数的时候,传递的参数L已经被定义好了为[], 第一次调用这个函数的话他会默认添加一个"END" 每次调用该函数,如果改变了L的内容,则下次调用时, 默认参数的内容就变了,不再是函数定义时的[]了。 解决上面问题

def add_end(L=None):
    if L is None:#判断有木有参数
        L=[]
    L.append('END')
    return L
print(add_end())#['END']
print(add_end())#['END']
print(add_end([1,2,3,4]))#[1, 2, 3, 4, 'END']

可变参数

在Python函数中,还可以定义可变参数。顾名思义,可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个

def get_ned(*combers):
    sum= 0
    for n in combers:
        sum = sum+n*n
    return sum

name = [1,2,3]
print(get_ned(1,2))
#   *nums表示把nums这个list的所有元素作为可变参数传进去
print(get_ned(*name))
print(get_ned())

关键字参数

可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。 而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict

def person (name , age , **kw):
    print('name:',name,'age:',age,'other',kw)
# person("王国慧",23)
# person("王国慧",23,web="vue",py="正在学习python")
# 函数person除了必选参数name和age外,还接受关键字参数kw。在调用该函数时,可以只传入必选参数:
# 关键字参数有什么用?
# 它可以扩展函数的功能。
# 比如,在person函数里,我们保证能接收到name和age这两个参数,但是,如果调用者愿意提供更多的参数,我们也能收到。
# 试想你正在做一个用户注册的功能,除了用户名和年龄是必填项外,其他都是可选项,利用关键字参数来定义这个函数就能满足注册的需求。
extra = {'city': 'vue', 'job': 'JavaScript'}
person('王国慧', 23, city=extra['city'], job=extra['job'])
person('王国慧', 23, **extra)
# **extra表示把extra这个dict的所有key-value用关键字参数传入到函数的**kw参数,
# kw将获得一个dict,注意kw获得的dict是extra的一份拷贝,对kw的改动不会影响到函数外的extra。

命名关键字参数

使用命名关键字参数时,要特别注意,如果没有可变参数,就必须加一个*作为特殊分隔符。如果缺少*,Python解释器将无法识别位置参数和命名关键字参数

def person (name ,age ,**kw):
    if 'cit' in kw:
        pass
    if 'job' in kw:
        pass
    print('name:',name,'age:',age,'other:',kw)
person("王国慧",23,cit="vue",job="javaScript",bbs="111")

def person(name, age, *args, city, job):
    print(name, age,args, city, job)
person('Jack', 24, city='Beijing', job='Engineer')

装饰器

1.装饰器可以让一个Python函数拥有原本没有的功能,也就是你可以通过装饰器,

def w1(func):
    print('装饰器开始装饰')
    def inner():
        print(".权限验证.")
        func()
    return inner
@w1
def f1():
   print('f1 cccccc')
f1()
  • 首先,开看我们的装饰器函数w1,该函数接收一个参数func,
  • 其实就是接收一个方法名,w1内部又定义一个函数inner,
  • 在inner函数中增加权限校验,并在验证完权限后调用传进来的参数func,
  • 同时w1的返回值为内部函数inner,其实就是一个闭包函数。
  • 然后,再来看一下,在f1上增加@w1,那这是什么意思呢?
  • 当python解释器执行到这句话的时候,会去调用w1函数,
  • 同时将被装饰的函数名作为参数传入(此时为f1),
  • 根据闭包一文分析,在执行w1函数的时候,此时直接把inner函数返回了,
  • 同时把它赋值给f1,此时的f1已经不是未加装饰时的f1了,而是指向了w1.inner函数地址
  • 接下来,在调用f1()的时候,其实调用的是w1.inner函数,
  • 那么此时就会先执行权限验证,然后再调用原来的f1(),
  • 该处的f1就是通过装饰传进来的参数f1。 添加参数
def log(func):
    print('解析器开始')
    def wrapper(*args, **kw):
        print(args,kw)
        print('添加内容')
        if args[0]>2:
            return func('我满足条件',)
        else:
            return func('我不满足条件')
        # print('call %s():' % func.__name__)
        # return func(*args, **kw)
    return wrapper
@log
def now(n):
    print(n,'2222')
# now(4)
# now(1)
# now(2,e=5)
now(2,3,4,e=1,m=3)