python(十三)--面向对象高级特性

1.类属性和实例属性

类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,在内存中只存在一个副本。

2. 类方法和静态方法

  • 类方法是类对象所拥有的方法,需要用修饰器一般以@classmethod来标识其为类方法,
    1). 对于类方法,第一个参数必须是类对象,作为第一个参数
    (cls是形参, 可以修改为其它变量名,但最好用’cls’了)
    2). 能够通过实例对象和类对象去访问。
  • 静态方法需要用修饰器一般以@staticmethod来标识其为静态方法,
    1). 静态方法不需要多定义参数
    2). 能够通过实例对象和类对象去访问。
"""
相关的源码: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()

在这里插入图片描述

3. property类属性

  • 一种用起来像是使用的实例属性一样的特殊属性,可以对应于类的某个方法。
    property属性的定义和调用要注意一下几点:
    1.定义时,在实例方法的基础上添加 @property 装饰器;并且仅有一个self参数
    2.调用时,无需括号

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

  • property属性的有两种方式:
    1.装饰器 即:在方法上应用装饰器
    2.类属性 即:在类中定义值为property对象的类属性

  • 注意:
    1.经典类中的属性只有一种访问方式,其对应被 @property 修饰的方法
    2.新式类中的属性有三种访问方式,并分别对应了三个被@property、@方法名.setter、@方法名.deleter修饰的方法

##简单案例

class date(object):
    def __init__(self,year,month,day):
        #私有属性
        self.__year = year
        self.__month = month
        self.__day = day
    @property     #将类方法转换成了类属性,只是让代码更加简洁而已
    def year(self):
        return self.__year
today = date(2021,2,27)
#print(today.year())   #2021  #不添加proptory装饰器的情况,可以简化代码(少了个括号)
print(today.year)   #2021     ##添加了装饰器的结果

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

4. 单例模式(设计模式的一种)

  • 简单来说就是一个类只能构建一个对象的设计模式。
  • 对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器。如在Windows中就只能打开一个任务管理器。如果不使用机制对窗口对象进行唯一化,将弹出多个窗口,如果这些窗口显示的内容完全一致,则是重复对象,浪费内存资源;如果这些窗口显示的内容不一致,则意味着在某一瞬间系统有多个状态,与实际不符,也会给用户带来误解,不知道哪一个才是真实的状态。因此有时确保系统中某个对象的唯一性即一个类只能有一个实例非常重要。

4.1 理解单例模式

##理解单例模式
"""
什么是单例模式?
一个类只能实例化一个对象的设计模式称为单例模式。
"""

class People(object):
    pass

p1 = People()  # object
p2 = People()  # object
print(p1, p2)  # 每个对象的内存地址不同,肯定不是单例模式

4.2 基于装饰器实现单例模式

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


p1 = People()
p2 = People()
print(p1, p2)
print(p1 is p2)  # 判断是否为单例模式(p1和p2内存地址是否相同)

4.3 基于new方法实现的单例模式

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)

4.4 总结

"""
面向对象:
    1. 三大特性
        封装(必须要掌握的):
            __new__: 在实例化对象之前执行的, 返回对象。
            __init__: 构造方法, 实例化对象时自动执行。 常用于将对象和属性绑定在一起。
            self: 实质上是对象。
        继承(最多知识点的):
            多继承算法: python3中广度优先算法。
            私有属性和私有方法
        多态(最简单的):

    2. 三大特性的应用
        1). 链表的封装(Leetcode第二题)
        2). 栈的封装
        3). 队列的封装
        4). 二叉树的封装与先序遍历

    3. 高级特性
        1). @classmethod和@staticmethod(类方法和静态方法)
        2). @property类属性
        3). 单例模式: 一个类只能实例化一个对象
            基于装饰器
            基于new方法
"""

猜你喜欢

转载自blog.csdn.net/qwerty1372431588/article/details/114179896
今日推荐