持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的20天,点击查看活动详情
👨🎓作者:Java学术趴
💌公众号:Java学术趴
🚫特别声明:原创不易,未经授权不得转载或抄袭,如需转载可联系小编授权。
🙏版权声明:文章里的部分文字或者图片来自于互联网以及百度百科,如有侵权请尽快联系小编。微信搜索公众号Java学术趴联系小编。
☠️每日毒鸡汤:这个社会是存在不公平的,不要抱怨,因为没有用!人总是在反省中进步的!
👋大家好!我是你们的老朋友Java学术趴。今天给大家分享一下如何在Python中创建一个单例模式。单例模式(Singleton Pattern)是 Python 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
17.3 Property属性
其实这个Property属性相当于Java中的Getter和Setter方法,专门就是用于对私有化属性就行操作的
上面我们为了访问私有化属性,需要两个公共方法提供给外部使用。其中一个是用来访问私有化属性的方法,一个是用来修改私有化属性的方法。那么,这样对于调用者来说 感觉就是在调用一个方法,并不是访问属性。如果我们想直接来访问Python类中的私有化属性,此时就需要使用Property属性
使用Property属性的本质还是通过方法进行访问,只不过是在调用者看来,可以直接通过属性来访问。其实本质还是调用的方法
注意:既然使用Property属性,那么获取私有化属性的时候必须存在 return 语句
# Property属性
class Animal(object):
# 私有化属性
__name = '小白'
# 获取私有化属性的方法(这个方法既然要当作Property属性,那么必须存在 return 语句)
def get_name(self):
return self.__name
pass
# 修改私有化属性的方法
def set_name(self, name):
self.__name = name
pass
# 定义一个Property属性实现直接通过访问属性的形式访问私有化的属性
name = property(get_name, set_name)
pass
dog = Animal()
# 使用Property属性直接调用类的私有化属性
print(dog.name)
# 小白
# 使用Property属性去修改类的私有化属性
dog.name = '大黑'
print(dog.name)
# 大黑
以上这种形式使用的是原始的Property属性,还可以使用装饰器的方式。如下
# Property属性(装饰器)
class Animal(object):
# 定义私有化属性
def __init__(self):
self.__name = '小白'
pass
# 使用Proper的装饰器模式。提供一个获取私有化属性的方法
# 这个name并一定要和私有化属性名一致,是自定义的,一般定义为私有化属性名
@property
def name(self):
return self.__name
pass
# 使用Pro的装饰器模式,提供一个修改私有化属性的方式
# 这个name.setter 中的name必须和 @property 声明的函数名一致,否则找不到
@name.setter
def name(self, name):
self.__name = name
pass
pass
dog = Animal()
# 使用Property属性直接调用类的私有化属性
print(dog.name)
# 小白
# 使用Property属性去修改类的私有化属性
dog.name = '大黑'
print(dog.name)
# 大黑
第十八章 _ _new__方法以及单例模式
18.1 _ _new__方法
概述:
- _ _new__方法的作用:创建并返回一个实例对象,调用一次new就会得到一个对象。继承自object的新式类才有new这个魔术方法
注意事项:
- new是在一个对象实例化的时候所调用的第一个方法
- new至少必须存在一个参数cls(可以自定义),代表的要实例化的类,此参数在实例化的时候由Python解析自动提供,其他的参数是用来直接传递给 init 方法
- new决定是否使用该init 方法,因为new方法可以调用其他类的构造方法或直接返回别的实例对象来作为本类的实例,如果new没有返回实例对象,则init不会被调用。
- 在new方法中,不能调用自己的new方法,即:return cls._ new_(cls),否则会报错(超过最大递归深度)
- new方法是一个静态方法
使用new方法的前提是:这个类必须继承了超类object,因为存在默认继承,所以可以省略不写
即使我们在类中没有写new方法,在创建类实例对象的时候Python也会默认自动调用,如果写了就调用我们自己写的new方法
# __new__方法和单例模式
class Animal(object):
def __init__(self):
print('调用__init__方法')
self.__name = '小白'
pass
def __new__(cls, *args, **kwargs):
print('调用__new__方法')
# 他会把这个返回的实例对象传递给 __init__函数,__init__函数中的self就是返回的这个对象
# 这里必须使用父类进行调用。使用 super().__new__(cls) 或者 object.__new__()
# 不可以使用 cls.__new__(cls) 的形式,会报错(maximum recursion depth exceeded 超过最大递归深度)
return object.__new__(cls)
pass
dog = Animal()
# 调用__new__方法
# 调用__init__方法
# new方法的执行要早于init方法
18.2 单例模式
概念:
单例模式是一种常用的软件设计模式,目的:确保一个类只存在一个实例对象
实现:
在实际开发中,创建一个单例对象,推荐使用 _ _new__去实现
# __new__方法实现单例模式
class Animal(object):
def __init__(self):
self.__name = '小白'
pass
def __new__(cls, *args, **kwargs):
# 加如一个创建的条件
if not hasattr(cls, '_instance'):
cls._instance = super().__new__(cls, *args, **kwargs)
pass
return cls._instance
pass
dog1 = Animal()
print(id(dog1))
# 1590192335984
dog2 = Animal
print(id(dog2))
# 1590192335984