python 类内部装饰器的实现 与 参数解构学习

学习了函数的装饰器的写法,然后想到如果要在类中初始化或获取信息时能用装饰器做过滤和验证应该怎么写呢,

在网上查了下相关信息,感觉这样也是可以的,不知道会不会有什么问题class Ctj():

class Ctj():
    sex = 'man'
    name = 'name'
    age = '16'

    def wrapper_func(func):
        # self 通过结构 可将需要单独使用的参数取出来
        # *args 获取位置参数的可变参数
        # **kwargs 关键字参数的可变参数
        def wrapper(self, *args, **kwargs):
            return func(self, *args, **kwargs)
        return wrapper

    def __init__(self, name=''):
        self.name = name

    @wrapper_func
    def get_name(self, a='1', b='2'):
        return self.name

    @wrapper_func
    def set_userinfo(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

    @wrapper_func
    def get_userinfo(self):
        print('hello')
        return 'name: %s, age: %s, sex: %s' % (self.name, self.age, self.sex)


if __name__ == "__main__":
    ctj = Ctj()
    ctj.set_userinfo('Carlos', '25', 'man')
    print(ctj.get_userinfo())

  其中要了解参数类型:

一、先普及下函数的定义

def 函数名(参数列表):
    函数体(代码块)
    [return 返回值] p

  Python的函数没有return语句,隐式会返回一个None

二、参数类型

  函数传入的参数是实参,定义函数时写的参数是形参,用于获取参数

  在python中经常会用到*args, **kwargs

1.位置参数的可变参数
在形参前使用*表示该形参是可变参数,可以接收多个实参
收集多个实参为一个tuple
*args,可以接受0到任意个参数
2.关键字参数的可变参数
形参前使用**符号,表示可以接收多个关键字参数
收集的实参名称和值组成一个字典
**kwargs,可以接受0到任意个参数
3.可变参数混合使用[*args中的参数可以通过参数名匹配单独提前取出,这里*args中将失去这个参数]
def showconfig(username, password, **kwargs, *args):  #**kwargs 不能放在*args之前
def showconfig(username, password, **kwargs) #username,password可以同时当作位置参数或者keywords参数
def showconfig(username, *args, **kwargs)     #username不能做关键字参数,关键字参数不能放在可变位置参数之前

  参数的其他用法及特点

  1、keyword-only参数

如果在一个星号参数后,或者一个位置可变参数后,出现的普通参数,实际上已经不是普通的 参数了,而是keyword-only参数
def fn(*args, x, y, **kwargs): #x,y放在位置可变参数之后,在传递实参的时候,必须要用关键字参数传递x,y否则会报错
args可以看做已经截获了所有的位置参数,x,y不使用关键字参数就不可能拿到实参 <br>def fn(y, *args, x=5):  #x 是 keyword-only参数

  2、keyword-only另外一种形式

def fn(*,x,y):
*号之后,普通形参都变成了必须给出的keyword-only 参数

  3、参数规则

参数列表参数一般顺序是,普通参数、缺省参数、可变位置参数、keyword-only参数(可带缺 省值)、可变关键字参数
def fn(x, y, z=3, *args, m=4, n, **kwargs):
1.x,y传递的实参不可省略
2.fn(100,99,98,97,m='a',n='b')    #位置参数超2个就会更该默认参数
3.fn(100,99,m='a',n='b')    #传递2个位置参数的时候默认参数生效

  4、参数解构

给函数提供实参的时候,可以在集合类型前使用*或者**,把集合类型的结构解开,提取出所有 元素作为函数的实参
非字典类型使用*解构成位置参数
字典类型使用**解构成关键字参数
提取出来的元素数目要和参数的要求匹配,也要和参数的类型匹配
def add(x, y):
add(4, 5)     #正常调用
add((4,5))     #错误调用被当做一个参数
add(*(4,5))    #参数解构
add(*range(1,3))
add(**{'a': 5, 'b': 6})      #解构value
add(*{'a': 5, 'b': 6})         #解构key

  5、参数解构例子

import random
def double_valuse(*nums):
    return max(nums),min(nums)
#调用1
x,y = double_valuse(*[random.randint(1,20) for i in range(10)])
print(x,y)

#调用2,print() 也是个函数,所以在打印的时候 double_vaules也可以参数解构
print(*double_valuse(*[random.randint(1,20) for i in range(10)]))

文章参考:https://www.cnblogs.com/harden13/p/8782782.html

原文地址:https://www.cnblogs.com/chentingjun/p/10237011.html