坚持原创输出,点击蓝字关注我吧
![](https://img-blog.csdnimg.cn/img_convert/a8e62464027390c44cf9bfc5e075997f.png)
目录
一、单例模式实现的思路
1.实现的思路
2.代码
3.通过单例模式可以做到什么
二、__str__方法和__repr__方法
三、__str__方法
一、单例模式实现的思路
1.实现的思路
![](https://img-blog.csdnimg.cn/img_convert/137f2825b36df416ae15a2690d4b24e7.png)
首先,定义一个类,叫做MyTest
,第一次创建对象t=MyTest()
。类创建对象用到了__new__
方法。通过__new__
方法创建对象,然后返回给t=MyTest()
。
然后第二次、第三次、第一百次创建对象的时候,同样通过MyTest
这个类去创建,可以通过__new__
方法来控制MyTest
这个类来创建实例对象的次数。
在__new__
方法里面可以加一些判断,判断下这个类有没有创建过实例化对象。如果这个类之前已经创建过对象了,那么这个时候__new__
方法就不会重新创建对象了,还是将之前创建的对象给你返回回来。
第一百次进去也是一样的,它发现你之前有创建过,始终给你返回的是第一次创建的那个对象。
「实现思路:」
可以通过__new__方法控制创建实例对象的次数,来实现一个单例模式。
在类里面给类定义一个属性,这个属性用来记录这个类有没有创建过实例化对象。如果这个类创建过对象,把这个属性改一下。
在__new__
方法里面,通过判断这个属性,来判断它之前有没有创建过实例化对象。
就像登录认证的那个装饰器,判断之前有没有登录过,可以通过token
啊,通过自己设定的值来判断。登录过之后,把这个值改掉。
如果它没创建过对象,就让它创建。创建过了,就把它对应的值改掉,下次再进来判断的时候,这个条件就不会成立了。
下次就不创建了,就把第一次创建的对象返回出去。第一次创建的对象,找个变量给它接收一下就行了。同样也可以用个类属性给它接收一下。
把它存储在类属性里面,然后第二次进来的时候,通过类属性把第一次创建的对象返回出去,第n次都是这样的。
2.代码
cls代表的是类本身。
# 单例模式
class MyTest(object):
instance=None#设置一个类属性用来记录这个类有没有创建过对象。
def __new__(cls, *args, **kwargs):
if not cls.instance:
cls.instance=object.__new__(cls)
return cls.instance
else:
return cls.instance
q1=MyTest
q1.name="清菡"
q2=MyTest
print(q2.name)
q3=MyTest()
print(id(q1))
print(id(q2))
print(id(q3))
#结果是:
清菡
2928962141896
2928962141896
2928994231968
# 单例模式
class MyTest(object):
instance=None#设置一个类属性用来记录这个类有没有创建过对象。None代表False
def __new__(cls, *args, **kwargs):
if not cls.instance:#not None为True。
cls.instance=object.__new__(cls)#not None为True,就进来这里了。
return cls.instance
else:
return cls.instance
q1=MyTest
q1.name="清菡"
q2=MyTest
print(q2.name)
q3=MyTest()
print(id(q1))
print(id(q2))
print(id(q3))
q3.age=19#q3能修改属性。
print(q3.age)
#结果是:
清菡
1794593781848
1794593781848
1794624788128
19
3.通过单例模式可以做到什么
1)你在这边创建个对象给它设置某个属性,在另外一个地方再创建一个对象再给它设置某个属性,那么,它们之间的属性是通用的。
2)还可以做到就是,这个类只创建一个对象MyTest()
,那么q1、q2、q3
始终指向的都是这个对象。可以节约内存
。
通过这个对象设置一些全局都可以用的东西
,只要在这个对象设置里面设置完毕之后,在别的地方再创建一个对象,创建完后直接访问之前其它地方设置好的属性,非常方便。
二、__str__方法和__repr__方法
交互环境下print打印的内容和直接输入变量,返回的内容不一样。
![](https://img-blog.csdnimg.cn/img_convert/c7550aaa0d84a6c085df3a5a2cbcd149.png)
为什么呢?
![](https://img-blog.csdnimg.cn/img_convert/9a771fd58a472a95abcf619dc8b079d4.png)
__str__
方法和__repr__
方法这两个方法。通过print
去打印的时候,触发的是__str__
这个魔术方法。
直接在交互环境里输入对象,触发的是__repr__
方法。
因为它们两个返回的内容不一样,所以在交互环境中print出来的结果和直接输入个变量出来的结果不一样。是因为它们底层触发的魔术方法不一样。
三、__str__方法
「注意:」
重写
__str__
方法和__repr__
方法的时候,必须一定要写return
。重写
__str__
方法和__repr__
方法的时候,return
返回的必须是一个字符串对象。
1.函数没有return,不写return,默认返回的是个None。
错误的代码:
class MyClass(object):
def __init__(self,name):
self.name=name
def __str__(self):
print("天气真好")
m=MyClass("清菡")
print(m)
2.返回的不是个字符串,返回的是个列表。
错误的代码:
![](https://img-blog.csdnimg.cn/img_convert/2a75223e4d690366c1f169362df36d1d.png)
class MyClass(object):
def __init__(self,name):
self.name=name
def __str__(self):
print("天气真好")
return[1,2,3]
m=MyClass("清菡")
print(m)
正确写法:
class MyClass(object):
def __init__(self,name):
self.name=name
def __str__(self):
return "天气很好"
m=MyClass("清菡")
print(m)
![](https://img-blog.csdnimg.cn/img_convert/090d8c567319836064cc1150b8d38734.png)
打印m
的时候,它打印的是__str__
方法给它返回的内容。__str__
方法给它返回的是什么,打印出来的就是什么。
如果通过__str__
方法打印的时候,想打印出来这个实例的属性。可以这样写:
class MyClass(object):
def __init__(self,name):
self.name=name
def __str__(self):
return self.name
m=MyClass("清菡")
print(m)
#结果是:
清菡
清菡软件测试,腾讯云年度最佳作者,非著名软件测试工程师。
除标明「图片来自网络」的图片,其它图片皆为清菡本人所画。计算机知识都一样,文章是清菡的笔记。如有雷同,纯属巧合。公众号 「清菡软件测试」 首发,更多原创文章:清菡软件测试 141+ 原创文章,欢迎关注、交流,禁止第三方擅自转载。如有转载,请标明出处。