某个服务器程序的配置信息存放在一个文件中,客户端通过一个 AppConfig 的类来读取配置文件的信息。如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 AppConfig 对象的实例,这就导致系统中存在多个 AppConfig 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。事实上,类似 AppConfig 这样的类,我们希望在程序运行期间只存在一个实例对象。
数据库配置文件 configuration.yml
- DB:
- host: 1
- username: 12
- password: 12
- database: 14
- databasetype: 15
- port: 33
- note: C
自定义类MyDbinfo,存储数据库配置
-
- import yaml
-
- from singleton import singleton
-
- @singleton
- class MyDbinfo(object):
- def __init__(self):
- _filePath = "/Users/zhaohui/PycharmProjects/TestSingleton/configuration.yml"
- f = open(_filePath, 'r', encoding='utf-8')
- cont = f.read()
- x = yaml.load(cont, Loader=yaml.FullLoader)
- self.host =x['DB']['host']
- self.username=x['DB']['username']
- self.password=x['DB']['password']
- self.database=x['DB']['database']
- self.port=x['DB']['port']
- self.note = x['DB']['note']
这里用到了注解的单例模式singleton
- def singleton(cls,*args,**kw):
- instances = {}
- def _singleton():
- if cls not in instances:
- instances[cls] = cls(*args,**kw)
- return instances[cls]
- return _singleton
调用一下试试
- from MyDbinfo import MyDbinfo
-
- myDbinfo1 = MyDbinfo()
- myDbinfo2 = MyDbinfo()
- if __name__ == '__main__':
- print(myDbinfo1)
- print(myDbinfo2)
打印结果:
- <MyDbinfo.MyDbinfo object at 0x7fb610194110>
- <MyDbinfo.MyDbinfo object at 0x7fb610194110>
两个实例的物理地址是一样的,说明是单例的。
新建一个类,DbInfo 存储数据库信息
-
- class DbInfo():
-
- # 在构造器里直接赋值,好像就不要写属性了。省了get和set方法了?
- def __init__(self,host=None,username=None,password=None,database=None,databasetype=None,port=None,note=None,charset="utf8"):
- self.host: str = host
- self.username: str= username
- self.password: str = password
- self.database: str = database
- self.databasetype: str = databasetype
- self.port: str = port
- self.note:str = note
- self.charset:str = charset
写一个读取方法,输入文件的地址,输出DbInfo
YmlUtil.py
-
- import yaml
-
- from DbInfo import DbInfo
-
-
- class YmlUtil():
-
- # path = os.path.abspath()
-
- @staticmethod
- def readDbYml(filePath:str) -> DbInfo:
- f = open(filePath, 'r', encoding='utf-8')
- cont = f.read()
- x = yaml.load(cont,Loader=yaml.FullLoader)
- print(x['DB'])
- print(x['DB']['host'])
- dbInfo=DbInfo(host=x['DB']['host'],
- username=x['DB']['username'],
- password=x['DB']['password'],
- database=x['DB']['database'],
- port=x['DB']['port']
- )
- # 设置类属性——setattr(object,key,value)
- # 类似于建造者模式
- setattr(dbInfo,"note",x['DB']['note'])
-
- return dbInfo
注解的单例模式:
singleton.py
- def singleton(cls,*args,**kw):
- instances = {}
- def _singleton():
- if cls not in instances:
- instances[cls] = cls(*args,**kw)
- return instances[cls]
- return _singleton
得到实体类的方法
- @singleton
- def getMyDbinfo():
- return YmlUtil.readDbYml("/Users/zhaohui/PycharmProjects/TestSingleton/configuration.yml")
测试一下得到实体类
- a = getMyDbinfo()
- b = getMyDbinfo()
- print(a)
- print(b)
打印结果:
- <DbInfo.DbInfo object at 0x7f9a783b0ed0>
- <DbInfo.DbInfo object at 0x7f9a783b0ed0>
这样得到的实体类,也是单例的。