オブジェクト向けアドバンスドC(メタクラス補完および単例モード)

6878 ワード

メタ関連知識ポイントの補足

#      

                  ,  School    name  xxx,    School.__dict__[‘name’] = ‘yyy’    “TypeError: 'mappingproxy' object does not support item assignment”                    ,     `a plain dict`,       ,      `mappingproxy`,      ,   __setattr__    

#class       
Person = type('Person', (object,), {})

def __init__(self, name, age):
    self.name = name
    self.age = age
p = type('Person', (object, ), {'x': 1, '__init__': __init__})
p1 = p('ljy', 19)

class Person:
    x = 1
    def __init__(self, name, age):
        self.name = name
        self.age = age
p = Person
q = p('ljy', 18)
print(p.__dict__)
print(q.__dict__)


# exec :         ,  python   

ss = '''
global x  #          
x = 1
y = 2
z = 3


print(y)

'''
g = {}
l = dict()
exec(
    ss, g, l
)

print(print(1))  #    1, None,  print     None

print(l) #   y=2    ,            
print(g) #         ,    x:2,      

#      ,  type

class Mymeta(type):
    def __init__(self, name, bases, dic):
        #self  Person   (  )
        #     ,  self   Person   ,
        #        ,          __new__
        #     dic       ,       
        #self.__dict__/self.      
        a = dic.get('name')
        if not a:
            raise Exception('  name  ,    ')
    def __call__(self, *args, **kwargs):
        pass

# class Person(metaclass = Mymeta):
'''
Person = Mymeta('Person', (object,), {...})
Mymete    ,        Mymeta __init__   
'''

class PersonException(metaclass=Mymeta):
        name = 'lae'#     ,          name   
    def __init__(self,name,age):
        self.name = name
        self.age = age
#            ,          
p1 = PersonException(18)
#      name  ,      ‘  name  ,    ’

class Person():
    def __init__(self, name):
        self.name = name
        raise Exception('      ')

p = Person('nick')
#     Person __init__   ,
#    :      
#   :         ,  __init__         


class Mymeta(type):
    def __init__(self, name, bases, dic):
        if 'name' not in dic.keys():
            raise Exception('  name  ,    ')
        else:
            self.__dict__['name'] = 'nick'
            '''
               TypeError: 'mappingproxy'
            object does not support item assignment
                          ,             
            (            )
            '''

class Person(metaclass=Mymeta):
    name = 'ljy'
    def __init__(self, name, age):
        self.name = name
        self.age = age
p = Person('ljy', 19)
print(p.name)
print(Person.name)


class Mymeta(type):
    def __call__(self, *args, **kwargs):
        #           (   ),
        #         , p=Person('lqz')
        #p    
        #       Person    
        #   :       
        # object.__new__(self)
        #      ,  ,            

        #obj Person     
        obj = object.__new__(self)

        # print(self.__new__ is object.__new__)
        #     True,  
        # self.__new__  object.__new__

        #   :      ,         
        #obj Person     ,obj.__init__  
        #         ,    Person    
        # __init__  
        obj.__init__(*args, **kwargs)
        #       
        Person.__init__(obj, *args, **kwargs)
        self.__init__(obj, *args, **kwargs)
        print(obj.name) #    lqz
        #   :      
        return obj
class Person(metaclass=Mymeta):
    def __init__(self, name):
        self.name = name
    def __call__(self, *args, **kwargs):
        print('XXXX')
p = Person('lqz')
print(p.name)
print(p)

単一モード
全部で23の設計モードがあり、単一のモードはプロセス全体に1つのインスタンスしかなく、生成されたすべてのインスタンスが同じ高速メモリ空間を指していることを意味します.
PORT = '192.384.28.2'
HOST = 2728
#   :        
#           ,            。
class Sql:
    _instance = None
    def __init__(self, port, host):
        self.port = port
        self.host = host
    @classmethod
    def singleton(cls):
        if not cls._instance:
            cls._instance = cls(PORT, HOST)
        return cls._instance
p1 = Sql.singleton()
p2 = Sql.singleton()
p3 = Sql('33306','192.168.1.1')#          ,        
print(p1)
print(P2)
print(p3)
'''
<__main__.sql object="" at="">
<__main__.sql object="" at="">
<__main__.sql object="" at="">
'''

##   :     
#   ,           
def get_singleton(cls):
    _instance = None
    def inner(*args, **kwargs):
        if len(args)!=0 or len(kwargs)!=0:
            res = cls(*args, **kwargs)
            return res
        else:
            nonlocal _instance
            if not _instance:
                _instance = cls(PORT, HOST)
            return _instance
    return inner

@get_singleton
class Sql:
    def __init__(self, port, host):
        self.port = port
        self.host = host
s1=Sql()
s2=Sql()
s3=Sql('33306','192.168.1.1') #  ,         
print(s1)
print(s2)
print(s3)
'''
<__main__.sql object="" at="">
<__main__.sql object="" at="">
<__main__.sql object="" at="">
'''

#   :      
#   ,           
class Mymeta(type):
    def __init__(cls, name, bases, dic):
        cls._instance = cls(PORT, HOST)
    def __call__(cls, *args, **kwargs):
        if len(args)!=0 or len(kwargs)!=0:
            obj = object.__new__(cls)
            obj.__init__(*args, **kwargs)
            return obj
        else:
            return cls._instance
class Sql(metaclass=Mymeta):
    def __init__(self, port, host):
        self.port = port
        self.host = host
p1 = Sql()
p2 = Sql()
p3 = Sql(8001, '178.23.4.53')#  ,         
print(p1)
print(p2)
print(p3)
"""
<__main__.sql object="" at="">
<__main__.sql object="" at="">
<__main__.sql object="" at="">

"""

#   :    
#singleton.py
class Sql():
    def __init__(self, port, host):
        self.port = port
        self.host = host
        
s1 = Sql(PORT, HOST)
        
#test.py
def test1():
    from singleton import s1
    print(s1)
def test2():
    from singleton import s1
    print(s1)

test1()
test2()
from singleton import s1
from singleton import Sql
s2 = Sql(477, '182.22.2.2')
print(s1)
print(s2)

'''





'''