Python之单列模式、魔术方法

# __init__:通常用来做属性初始化或赋值操作,实例化的时候会自动调用
class Test(object):
    def __init__(self):
        print('这是init方法')

# 实例化对象
te = Test()
print(te)  # 内存地址


'''
__new__是一个由object基类提供的内置静态方法,主要作用有两个:
1.在内存中为对象分配空间
2.返回对象的引用
'''

'''
重写new方法
1、父类名.方法名(self)
2、super().方法名()
3、super(子类名,self).方法名()
'''
# 写一个new方法
class Test(object):
    name = 'Ustinian'  # 类属性
    def __init__(self):
        print('这是self:', self)
        print('这是init方法')

    # __new__()是内置静态方法,需要cls参数
    def __new__(cls):
        print('new中的cls:', cls)
        print('这是new方法')
        # 重写new方法
        res = super().__new__(cls)  # 方法的重写,res里面是实例对象的引用
        # print(res)
        return res  # 返回对象引用

# 实例化对象
te = Test()
print(te)  # 内存地址
# print(dir(object))

# 小结:
# 问题总结:
# 1、init方法是在什么时候调用的?
# 在创建一个对象时默认被调用,不需要手动调用,实例化的时候调用
# 2、new方法是用来干什么的?它是从哪里来的
# new方法是用来创建实例化对象 object自带
# 查看类里面的所有属性和方法
# 内置函数dir():返回模块的属性列表和方法列表
print(dir(object))
print(dir(Test))
# 3、self是什么?
# self代表实例化对象本身,它是new方法创建,然后传递init方法使用

# 执行步骤:一个对象实例化的过程:先执行new方法,如果没有写new方法,
# 默认调用object里面的new方法,返回一个实例对象,然后再调用init方法,对这个对象进行初始化

# 综合案例:创建一个人类,有一个name实例参数,同时需要重写new方法
class Person(object):
    def __init__(self, name):
        self.name = name  # 实例属性
        print('这是init方法')
        print('名字是:', self.name)

    # 重写new方法
    def __new__(cls, *args, **kwargs):  # 创建对象
        print('这是new方法')
        print('这是new方法中需要返回的值:', super().__new__(cls))
        return super().__new__(cls)  # 重写new方法,返回对象引用

p1 = Person('Ustinian')
print('这是第一次实例化对象:', p1)
p2 = Person('us')
print('这是第二次实例化对象:', p2)


# 执行步骤:
# 1、执行new方法
# 2、重写new方法,返回对象引用,创建实例化对象
# 3、利于这个实例化对象调用init方法
# 4、执行init里面的代码

# 总结:
# init和new的区别:
# 1、new方法:创建对象  init方法:创建初始化对象
# 2、new方法:返回对象引用(内存地址)  init方法:定义实例属性
# 3、new方法:是类级别的方法  init方法:是实例级别的方法


class A(object):
    pass

a1 = A()
print(a1)
a2 = A()
print(a2)
a3 = A()
print(a3)
# 普通模式下每实例化一次就会产生一个新的内存地址,实例化不同的对象,内存地址是不相同的
# 单例模式:不管实例化多少次都是同一个内存地址
'''
1. 定义一个类属性,初始值是None,用来记录单例对象的引用
2. 重写__ new__方法
3. 进行判断,如果类属性是None,把new方法返回的对象引用保存进去
4. 返回类属性中记录的对象引用
'''
# 实现单例模式需求:回收站初始化
# 1、定义类,类中需要有init和new方法
class Recycle(object):
    # 2、定义一个类属性,初始值是None,记录第一个被实例化的对象引用
    ins = None  # 类属性
    # 3、重写__new__方法,在类中使用new方法给创建的每一个对象分配内存地址,并且保证内存地址是同一个
    def __new__(cls, *args, **kwargs):
        # 1、判断类属性是否为空
        if cls.ins == None:
            # 2、把new方法返回的对象引用保存进去,调用父类的new方法,为第一个对象分配空间
            cls.ins = super().__new__(cls)
        return cls.ins  # 返回类对象的引用

    def __init__(self):  # 为了检测对象是否创建成功
        print('这是init方法')

# 实例化对象
r1 = Recycle()
print('r1', r1)
r2 = Recycle()
print('r2', r2)
# 内存地址是不一样的,要实现的效果是第二次实例化是同一个地址


# 魔术方法
# class A:
#   pass
# print(dir(A))

# __doc__:表示类的描述信息
class A(object):
    '''这是A类的描述信息'''
    pass

# 类名.__doc__
print(A.__doc__)

# 2、__str__:对象的描述信息
# str方法必须返回一个字符串
class B(object):
    def __str__(self):
        return 'Ustinian'  # 返回值:必须有,而且一定是字符串类型

b = B()
print(b)

# 3、__mro__:显示指定类的所有继承脉络和继承顺序
class C(A, B):
    pass

print(C.__mro__)

# 4、__module__表示当前操作的对象在那个模块
# 导入模块
# import py01
# p1 = py01.A()
# print(p1.__module__)  # 输出的是模块

# 5、__class__表示当前操作的对象类是什么
# from py01 import B
# p1 = B()
# print(p1.__class__)  # 输出类
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值