python怎么传参数,怎么写装饰器decorator()

2018.03.12
author: wills

在python中,不管是传一个参数,还是多个参数,又或者部分参数要求参数名,部分参数不需要函数名,都有严格的语法要求。

一,多个参数,不知道有没有参数名

def say_hello(*args,**kwargs):


def say_hello(*args,**kwargs):
    if 'name' in kwargs:
        print('你好,%s!' % kwargs['name'])
    elif 'age' in kwargs:
        age = kwargs['age']
        if age <= 15:
            print('你还小')
        else:
            print('你是大人了')
    else:
        print('你是谁')
    print(args)
    print(kwargs)

关键字参数(**kwargs) :传进来—->一个字典—->根据参数名决定如何执行

可变参数(*args):传进来的是一个元组tuple

如果想直接传字典作为可变关键字参数,需要在字典前面加 ‘**’

    dict1 = {'name':'will','age':22}
    say_hello(**dict1)

如果直接传元组,列表作为可变参数,需要在元组,列表前加 ‘*’

    tuple = (1,2,34,5)
    say_hello(*tuple)

命名关键字参数

## 命名关键字参数 ,* 后面的参数,必须给参数名,前面的可给可不给
def foo(a,e,d,*,name,age):
    print(a+e+d)
    print('%s' % name +':'+'%s' % age)

foo(a=1,d=33,e=123,name='gppd',age=12)
foo(2,2,3,name='will',age=85)

高阶函数

为了提高函数的通用性,又要符合函数高内聚的特性,我们可以把简单函数当做参数传入函数里,构成一个根据参数不同实现不同功能的高级函数,这就是高阶函数。见下例

def cal(list,op):
    total = list[0]
    for x in range(1,len(list)):      
        total = op(total,list[x])
    return total 
# 通过向函数中传入函数,可以写出更通用的代码
# cal 函数中第二个参数是另一个函数,他代表了一个二元运算
# 这样cal函数就不需要和某个特定二元运算耦合在一起
# 所以cal函数变得通用性更强,可以由传入的第二个参数决定函数到底做什么
# 高内聚,低耦合  high cohesion low coupling
# 高内聚:函数做好一件事就好了
def add(x,y):
    return x+y
def mul(x,y):
    return x * y

lis=[1,3,5]
print(cal(lis,add))
print(cal(lis,mul))

很重要的函数方法decorator(),它的作用是装饰另一个函数使得另一个函数自身不变的情况下拥有更多的功能

def record(fn):
    def wrapper(*args,**kwargs):
        print('准备执行%s函数 ' % fn.__name__)
        print(args)
        print(kwargs)

        # 此时正在执行被装饰的函数
        # 在这行代码的前后我们可以附加其他代码
        # 这些代码可以让我们在执行函数时做一些额外的工作
        val = fn(*args,**kwargs)

        print('执行%s函数之后。。。' % fn.__name__)
        print('return %d' %val)      
        return val
        # 返回被装饰函数的执行结果       
    return wrapper

# 通过装饰器修饰f函数,让f函数在执行时可以做更多额外的操作
@record
def f(n):
    if n == 0 or n == 1:
        return 1
    return n * f(n-1)

if __name__ == '__main__':
    print(f(5))

命名关键字参数 ,* 后面的参数,必须给参数名,前面可给可不给

def foo(a,e,d,*,name,age):
    print(a+e+d)
    print('%s' % name +':'+'%s' % age)

foo(a=1,d=33,e=123,name='gppd',age=12)
foo(2,2,3,name='will',age=85)
def record(fn):
    def wrapper(*args,**kwargs):
        print('准备执行%s函数 ' % fn.__name__)
        print(args)
        print(kwargs)

        # 此时正在执行被装饰的函数
        # 在这行代码的前后我们可以附加其他代码
        # 这些代码可以让我们在执行函数时做一些额外的工作
        val = fn(*args,**kwargs)

        print('执行%s函数之后。。。' % fn.__name__)
        print('return %d' %val)      
        return val
        # 返回被装饰函数的执行结果

    return wrapper
# 通过装饰器修饰f函数,让f函数在执行时可以做更多额外的操作
@record
def f(n):
    if n == 0 or n == 1:
        return 1
    return n * f(n-1)

if __name__ == '__main__':
    print(f(5))

下面就是递归求阶乘函数被装饰后运行过程,可以更清楚的看到被装饰函数f(n)每一步是怎么运行的

准备执行f函数
(5,)
{}
准备执行f函数
(4,)
{}
准备执行f函数
(3,)
{}
准备执行f函数
(2,)
{}
准备执行f函数
(1,)
{}
执行f函数之后。。。
return 1
执行f函数之后。。。
return 2
执行f函数之后。。。
return 6
执行f函数之后。。。
return 24
执行f函数之后。。。
return 120
120

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值