Python高阶(五)--装饰器高级,单例模式

一.怎么为类添加装饰器

为类添加装饰器时,就是在装饰器后加一个cls,代码:

def some_func(cls):
    return cls


@some_func
class A(object):
    pass


if __name__ == '__main__':
    a = A()

二.用类装饰某个函数

import time


class A(object):
    def __init__(self, func):
        self.func = func
        print('-------')

    def __call__(self, *args, **kwargs):  # __call__当对一个对象加()进行调用时,此方法会自动执行
        # 当对一个对象加()进行调用时,此方法会自动执行
        print(f"{self.func.__name__}函数运行前")
        start = time.time()
        result = self.func(*args, **kwargs)
        print(f"{self.func.__name__}函数运行后")
        end = time.time()
        print(f"{self.func.__name__}执行时间为{start - end}")
        return result


@A
def f(a, b):
    time.sleep(1)
    print('123')
    pass


@A
def q(w):
    time.sleep(1)
    print(w)


if __name__ == '__main__':
    # 因为类和函数可以直接加括号,但是由类创建的对象一般是不能加括号的,所以要在类里加一个__call__属性,否则会报错
    f(1, 2)
    q(1)

三.带参数的装饰器

带参数的装饰器,就是装饰器会接受一个或多个变量,例如在log中,传入文件名称


def log(filename: str):
    print(filename)

    def inner(func):
        print(f'{func.__name__}')

        def wrapper(*args, **kwargs):
            print(args)
            func(*args, **kwargs)
        return wrapper

    return inner


@log(filename='info.log')
def add(a, b):
    return a + b


add(1, 2)

四.callable
callable 属性:一个函数或类里的元素包含此属性的话,可以直接加括号用


def add(x, y):
    return x + y


class MyClass(object):
    pass


class MyClass2(object):
    def __call__(self, *args, **kwargs):
        pass


print(callable(add))  # True
print(callable(MyClass()))  # False
print(callable(MyClass2()))  # True

五._ new init _的区别

class Person(object):
    def __init__(self, name):
        self.name = name
        print('初始化对象的值')

    def __new__(cls, *args, **kwargs):
        print('开始创建对象并分配内存')
        return super().__new__(cls)


class Student(Person):
    def __init__(self, name, stu):
        super(Student, self).__init__(name)

    def study(self):
        pass


class Teacher(Person):
    pass


if __name__ == '__main__':
    xiaomimg = Person('小明')

六.单例模式

"""
单例模式: 只有一个实例
实现方法: 
    1.import
    2.单例模式
    3.装饰器
"""


class Person(object):
    obj = None

    def __init__(self, name):
        # self.name = name
        pass

    def __new__(cls, *args, **kwargs):
        # 如果对象已经创建,就直接把创建好的对象返回
        # 如果对象没有创建,就创建对象并返回
        if cls.obj is None:
            cls.obj = super().__new__(cls)  # 分配内存
        return cls.obj


if __name__ == '__main__':
    xiaoming = Person('小明')
    xiaohong = Person('小红')
    print(xiaohong is xiaoming)  # False
    print(id(xiaohong), id(xiaoming))

七.总结

1.什么是单例模式(使用场景)

单例模式某个类就是只会创建一个对象,再此创建时,会把创建好的对象返回。使某个类只有一个实例。

应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。

Web应用的配置对象的读取,一般也应用单例模式,这个是由于配置文件是共享的资源。

2.什么是装饰器,带参数的装饰器的调用过程

所谓的装饰器,其实就是通过装饰器函数,来修改原函数的一些功能,使得原函数不需要修改
因为带参数的装饰器基本都是三层封装,拿下面的代码举例:
  先将@log(filename='info.log')传给def log(),
  执行下面的代码后,就可以看成下面代码的装饰器是@inner,
  然后就是不带参数的装饰器的执行过程。
def log(filename: str):
    print(filename)

    def inner(func):
        print(f'{func.__name__}')

        def wrapper(*args, **kwargs):
            print(args)
            func(*args, **kwargs)
        return wrapper

    return inner


@log(filename='info.log')
def add(a, b):
    return a + b

3.__new__和__init__的区别和联系

1. __new__是构造方法,__init__是初始化函数。
2.__new__通常不需要手动定义,一般在元类编程中使用,控制类的生成过程。
3.__new__第一个被执行,然后执行__init__绑定实例变量。
4.__new__必须有返回值,返回值是该类的实例,它会被__init__函数接收,通常叫做self变量

4.super是什么

super,名为超类,可以简单的理解为执行父类的__init__函数
  我们可以把python中类的继承理解成这样的一个过程:
当我们在括号中明确了父类时,其实已经引用了父类的成员函数,但是并没有执行父类的初始化函数。
在执行子类的初始化函数的同时,会检查是否重载了父类的成员函数,如果重载则会直接覆盖。
而只有在执行了super之后,才相当于执行了父类的初始化函数,此时才可以访问父类的成员变量。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值