Singleton:确保每一类只有一个实例,并且提供对这个实例的全局访问
通常用于需要共享的资源。例如数据库对象 
Singleton还是一种有效保护使变量免遭改写的技术 
 
 
实现方法
构造函数私有化 
用一个静态函数作为constructor,通过它创建一个新对象并存储在一个静态空间里 
 
Python中的实现有一些魔法,其中一个就是Python中任何东西都是对象,包括类本身也是对象。type本质上不是类,而是一个元类。type(1)输出结果是<class 'int'>,表明它创建了一个类!
实际上也可以这样写:
1 2 type (Foo, (object ,), {"a" :1 })
使用元类的目的:控制类的产生过程和对象的产生过程。继承type就可以产生元类。例如可以控制一个类必须要有文档(参考 ):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class  Mymeta (type ):    def  __init__ (self, class_name, class_bases, class_dic ):         if  class_dic.get('__doc__' ) is  None  or  \                 len (class_dic.get('__doc__' ).strip()) == 0 :             raise  TypeError('This class must have docstring!' )         if  not  class_name.istitle():             raise  TypeError('First letter in class name should be capitalized!' )         super (Mymeta, self).__init__(class_name, class_bases,                                      class_dic) class  People (object , metaclass=Mymeta):    country = 'China'      def  __init__ (self, name, age ):         self.name = name         self.age = age     def  eat (self ):         print ('%s is eating'  % self.name) 
判断一个对象最好的办法是isinstance,因为可以用来处理子类的情况:isinstance(True, int) == True!
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class  SingletonMeta (type ):    _instances = {}     def  __call__ (cls, *args, **kwargs ):         if  cls not  in  cls._instances:             instance = super ().__call__(*args, **kwargs)             cls._instances[cls] = instance         return  cls._instances[cls] class  Database (metaclass=SingletonMeta):    def  __init__ (self, db_conn: str  ) -> None :         self.db = DBConn(db_conn)          def  query (self, sql:str  ):         session = self.db.create_session()         return  session.query(sql) if  __name__ == "__main__" :    db = Database("mysql://database" )     db.query("SELECT ..." )     db = Database("mysql://database" )     db.query("SELECT ..." ) 
cpp中关于static的用法说明:
修饰静态成员变量:需要在类外部定义和初始化,因为它们不是在对象被创建时实例化的,而是在程序开始运行时(在进入 main 函数之前)就已经分配好了内存。 
修饰静态成员函数:是类的一部分,但它们不依赖于类的特定实例。这意味着它们不能访问类的非静态成员变量或调用非静态成员函数。 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 class  Database  {  private :     static  Database* pdatabase_;     static  std::mutex mutex_;   protected :     Database (const  std::string dbconn) : dbconn_ (dbconn) {}     ~Database () {}     std::string dbconn_;   public :     Database (Database &other) = delete ;      void  operator =(const  Database &) = delete ;     static  Database* GetInstance (const  std::string& dbconn)      ReturnType query (std::string sql)   {            } }; Database* Database::pdatabase_{nullptr }; std::mutex Database::mutex_; Database* Database::GetInstance (const  std::string& dbconn)   {     std::lock_guard<std::mutex> lock (mutex_)  ;   if  (pdatabase_ == nullptr ) pdatabase_ = new  Database (dbconn);   return  pdatabase_; } void  ThreadFoo () {  std::this_thread::sleep_for (std::chrono::milliseconds (1000 ));   Database* db = Database::GetInstance ("sql://cool" );   std::cout << db->query ("SELECT ..." ) << "\n" ; } void  ThreadBar ()    std::this_thread::sleep_for (std::chrono::milliseconds (1000 ));   Database* db = Database::GetInstance ("sql://another_cool" );   std::cout << db->query ("SELECT ..." ) << "\n" ; } int  main ()    std::thread t1 (ThreadFoo)  ;   std::thread t2 (ThreadBar)  ;    t1.join ();   t2.join ();      return  0 ; }