python装饰器及魔法函数

一. 装饰器

python的装饰器其实就是在某个函数外面再嵌套一个函数,用以达到增强该函数功能的效果。其实就是 套娃

特点

装饰器输入参数:函数

装饰器输出:函数

装饰器使用:能使代码使用上更加简洁

比如下面的例子:

def wrapper(f):
    def a(*args, **kwargs):
        print(*args, **kwargs)
        f(*args, **kwargs)
    return a

# 1. 未使用装饰器情况下
def call(name):
    print(f'name:{name}')

wrapper(call('张三'))

# 2. 使用装饰器
@wrapper
def call(name):
    print(f'name:{name}')

call('张三')

1.1 classmethod装饰器

一般来说,使用一个类的方法,必须先实例化该类,再调用方法。但是@staticmethod则可以直接使用类名.方法()。其特点

1. 方法内部参数不能有self。

2. 类的其他方法调用本方法需要加入self.方法()

3. 在方法内部调用类其他属性为 类名.属性,调用方法则需要先实例化。

class A:
    c = 'c'

    @staticmethod
    def a(a = 1):
        print(a)
        print(A.c)
        A().cc() # 需要实例化

    def b(self):
        self.a() # 正常调用

    def cc(self):
        print(self.c)

A.a() # 不用实例,即可外部调用

1.2 classmethod装饰器

和staticmethod一样,可以不需要实例,直接直接使用类名.方法()。

特点

1. classmethod没有类实例化对象的self参数,而是指代类本身的cls参数。

2. 类的其他方法调用本方法需要加入self.方法()

3. 在方法内部调用类其他属性为 cls.属性,调用方法则需要先实例化 cls.方法()。

class A:
    c = 'c'

    @classmethod
    def a(cls,a = 1):
        print(a)
        print(cls.c)
        cls().cc() # 需要实例化

    def b(self):
        self.a() # 正常调用

    def cc(self):
        print(self.c)

A.a()

1.3 property 装饰器

作用: 修饰方法,将方法当作类的只读属性一样访问,能防止属性被修改。

class A:
    aaa = 1

    @property
    def a(self): 
        return self.aaa

    def b(self): 
        return self.aaa

a = A()
print(a.a) 
print(a.b())

二. 魔法函数

2.1 new函数

场景:一般需要使用单例模式下(比如数据库连接等),需要确保只有单个对象被创建情况下,都需要用到new函数

class A:
    _instance = None

    def __new__(cls, *args, **kwargs):
        print('__new__')
        # 单例模式下,先判断是否存在实例,没有则创建
        if cls._instance is None:
            cls._instance = object.__new__(cls)
        return cls._instance

    def __init__(self):
        print('__init__')


# 仅允许一个实例被创建,就算创建其他实例,本质指向的还是同一个实例
a = A()
b = A() # a ==> b

# 打印结果:先是 __new__ 后是__init__。说明new是在实例创建之前,而init则是在实例创建之后

2.2 call函数

场景:将一个类当作一个函数进行使用,在流水线式的数据处理时可以更好的进行封装。

class A:
    def __call__(self, *args, **kwargs):
        return self.compute(*args, **kwargs)

    def a1(self,a,b):
        return a + b

    def a2(self,a,b):
        return a * b

    def compute(self,a,b,c):
        return self.a1(a,c) + self.a2(a,b)

a = A()
rs = a(1,2,3) # 首先需要实例化,之后可以直接像函数一样使用

2.3 属性操作add

场景: 需要对2个实例进行运算操作时

class A:
    def __init__(self, a) :
        self.a = a
    def __add__(self, other_a):
        return self.a + other_a.a

a1 = A(1)
a2 = A(2)
aa = a1 + a2

2.4 eq函数和hash函数
场景:同一个类,实例的2个对象进行判断是否完全相同。这里的eq和hash一般是同时出现才可。

class A:
    def __init__(self,a):
        self.a = a

a1 = A(3)
a2 = A(3)
print(a1 == a2) # 输出是False,原因是2个对象的地址不同

class B:
    def __init__(self,a):
        self.a = a
    
    def __eq__(self,other):
        if type(other) == type(self) and other.a = self.a:
            return True
        else:
            return False

    def __hash__(self):
        return hash(self.a)


b1 = B(3)
b2 = B(3)
print(b1.__eq__(b2)) # 同下
print(b1 == b2) # 输出是True,利用eq函数进行判断,如果是,则2个对象地址应是一样
  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值