某個服務器程序的配置信息存放在一個文件中,客戶端通過一個 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>
這樣得到的實體類,也是單例的。