• 【python】类方法、property类属性、单例模式


    一、类方法

    实例方法(默认): python解释器会自动将对象/实例传入方法。
    类方法(@classmethod):python解释器会自动将类传入方法。
    静态方法 ( @staticmethod):python解释器不会自动传入任何参数

    """
    相关的源码:from datetime import  datetime
    """
    
    class Student(object):
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        # 实例方法, python解释器会自动将对象/实例传入方法。
        def get_age(self):
            print('self:', self)
            return  self.age
    
        # 类方法:python解释器会自动将类传入方法。
        @classmethod
        def get_cls(cls):
            print('cls:', cls)
    
        # 静态方法:python解释器不会自动传入任何参数
        @staticmethod
        def get_info():
            print("static method信息")
    
    if __name__ == '__main__':
        s = Student('张三', 18)
        s.get_age()
        s.get_cls()
        s.get_info()
    
    #结果
    self: <__main__.Student object at 0x00000212733F6530>    #传入示例
    cls: <class '__main__.Student'>                          #传入类名                                          
    static method信息                                        #什么都不传入                           
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    二、property类属性

    可以将类方法定义为类属性,调用时就不用加(),类似于于调用了一个变量,察觉不到自己调用了一个函数。

    例题
    在这里插入图片描述

    类属性应用需求: 对于京东商城中显示电脑主机的列表页面,每次请求不可能把数据库中的所有内容都显示到页面上,而是通过分页的功能局部显示,所以在向数据库中请求数据时就要显示的指定获取从第m条到第n条的所有数据 这个分页的功能包括:
    1、 根据用户请求的当前页和总数据条数计算出 m 和 n
    2、根据m 和 n 去数据库中请求数据

    from datetime import  datetime
    """
    
    class Page(object):
        """
        [user1, user2, user3......user100]
        page=2, per_page=10
        第一页: start=0 end=10
        第二页: start=10 end=20
        第三页: start=20 end=30
        ....
        第page页: start=(page-1)*per_page end=page*per_page
        """
        def __init__(self, page, per_page=10):
            self.page = page
            self.per_page = per_page
    
        # 类属性: 将类方法变成类属性的过程。
        @property
        def start(self):
            return (self.page-1) * self.per_page
    
        @property
        def end(self):
            return  self.page * self.per_page
    
    if __name__ == '__main__':
        goods = ['good'+str(i+1) for i in range(100)]
        page = Page(page=10, per_page=3)
        print(goods[page.start:page.end])                      #因为类属性所以page.start()可以改为page.start
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    三、单例模式

    1、基本认识
    一个类只能构建一个对象的设计模式
    单例模式的地址不同

    class People():
        pass
    
    p1 = People()
    p2 = People()
    print(p1, p2)
    print(p1 is p2)  # 判断是否为单例模式(p1和p2内存地址是否相同)
    #结果
    <__main__.People object at 0x000002272C502560> <__main__.People object at 0x000002272C502650>
    False
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2、基于装饰器的实例化

    1、为了保证单例模式, 判断该类是否已经实例化为对象
    2、 如果有对象,直接返回存在的对象
    3、如果没有则实例化对象, 并存储类和对象到字典中, 最后返回对象
    
    • 1
    • 2
    • 3
    from functools import  wraps
    def singleton(cls):
        # 通过一个字典存储类和对象信息{"Class":"object"}
        instances = {}
        @wraps(cls)
        def wrapper(*args, **kwargs):
            # 为了保证单例模式, 判断该类是否已经实例化为对象
            # 1. 如果有对象,直接返回存在的对象
            # 2. 如果没有则实例化对象, 并存储类和对象到字典中, 最后返回对象
            if instances.get(cls):
                return instances.get(cls)
            object = cls(*args, **kwargs)
            instances[cls] = object
            return  object
        return  wrapper
    
    @singleton
    class People(object):
        pass
    
    class People():
        pass
    
    p1 = People()
    p2 = People()
    print(p1, p2)
    print(p1 is p2)  # 判断是否为单例模式(p1和p2内存地址是否相同)
    #结果
    <__main__.People object at 0x0000020350F37FD0> <__main__.People object at 0x0000020350F37E80>
    False
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    3、基于new方法实现的单例模型

    1、new方法就是一个创建的·过程
    2、类方法在创建对象之前执行
    3、在new方法之后执行, 将属性和对象封装在一起
    
    • 1
    • 2
    • 3
    class People(object):
        _instance = None
    
        def __new__(cls, *args, **kwargs):
            """创建对象之前执行的内容"""
            if cls._instance is None:
                cls._instance = object.__new__(cls)
            return  cls._instance
    
        def __init__(self):
            """在new方法之后执行, 将属性和对象封装在一起"""
            print("正在执行构造方法init......")
    
    p1 = People()
    p2 = People()
    print(p1, p2)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    GitHub+Hexo博客搭建
    入门简单,轻量好用的低代码开发平台推荐
    【数仓】Hadoop软件安装及使用(集群配置)
    四十分钟带你玩儿转Python-OpenCV(一)
    面向对象
    神经网络与深度学习(四)
    学Cocos Creator 3.8.0链接GoWorld自带示例ChatRoom
    docker网络与docker自定义网络建立
    【MongoDB】docker安装mongodb 7.0
    Python学习----异常、模块、安装第三方包
  • 原文地址:https://blog.csdn.net/weixin_48819467/article/details/125608686