元类,__call__方法和单例模式
Posted Ryansuperwa
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了元类,__call__方法和单例模式相关的知识,希望对你有一定的参考价值。
在python中一切皆对象的概念。
举一个例子:
class Chinese: country=“china” def __init__(self, name,age,sex): self.name=name self.age=age self.sex=sex def change(self): print(‘%s speak Chinese ‘%self.name) #一切皆对象的原则。 那么这个类Chinese也是对象,那么他也有自己的类。那么他的类就是type
元类:类的类就是元类。
我们用class定义类的使用来生产我们自己的对象的
内置元类type是用来专门产生class定义的类的
但是如何产生的呢?
用内置的元类type,来实例化得到我们的类
class_name=("Chinese") class_bases=(object,)#元组 class_boby=‘‘‘
country=“china”
def __init__(self, name,age,sex): self.name=name
self.age=age
self.sex=sex
def change(self):
print(‘%s speak Chinese ‘%self.name)
‘‘‘#类体代码 type()#类名字 基类 和名称空间
class_dic={}
exec(class_boby,{},class_dic)
print(class_dic)#产生了类的名称空间
#类的三大要素凑齐了
print(class_name,class_bases,class_dic)
#实例化了
Chinese=type(class_name,class_bases,class_dic)
#print(Chinese)
p=Chinese(‘egon‘,18,‘male‘)
print(p.name,p.age,p.sex)
我们为毛要用这种方法来自定义类呢?
是因为这样我们就了解了,类的底层原理,这样就可以控制类的定了
##储备知识__call__方法
class Foo: def __init__(self):#定义的时候自动触发 pass def __str__(self):#在打印的时候自动触发 pass def __del__(self):#在删除的时候自动触发 pass def __call__(self,*args,**kwargs):#在调用的时候自动触发 print(”__call__“) obj=Foo() #怎么调用? obj(1,2,3,x=1,y=2,z=3)
3、自定义元类:
class Mymeta(type): # # 来控制类Foo的创建 # def __init__(self,class_name,class_bases,class_dic): #self=Foo # # print(class_name) # # print(class_bases) # # print(class_dic) # if not class_name.istitle(): # raise TypeError(‘类名的首字母必须大写傻叉‘) # # if not class_dic.get(‘__doc__‘): # raise TypeError(‘类中必须写好文档注释,大傻叉‘) # # super(Mymeta,self).__init__(class_name,class_bases,class_dic) # # # 控制类Foo的调用过程,即控制实例化Foo的过程 # def __call__(self, *args, **kwargs): #self=Foo,args=(1111,) kwargs={} # # print(self) # # print(args) # # print(kwargs) # # #1 造一个空对象obj # obj=object.__new__(self) # # #2、调用Foo.__init__,将obj连同调用Foo括号内的参数一同传给__init__ # self.__init__(obj,*args,**kwargs) # # return obj # # # # #Foo=Mymeta(‘Foo‘,(object,),class_dic) # class Foo(object,metaclass=Mymeta): # """ # 文档注释 # """ # x=1 # def __init__(self,y): # self.Y=y # # def f1(self): # print(‘from f1‘) # # # obj=Foo(1111) #Foo.__call__() # # # print(obj) # # print(obj.y) # # print(obj.f1) # # print(obj.x) # 单例模式 import settings class mysql: __instance=None def __init__(self,ip,port): self.ip=ip self.port=port @classmethod def singleton(cls): if not cls.__instance: obj=cls(settings.IP, settings.PORT) cls.__instance=obj return cls.__instance obj1=MySQL(‘1.1.1.2‘,3306) obj2=MySQL(‘1.1.1.3‘,3307) obj3=MySQL(‘1.1.1.4‘,3308) # obj4=MySQL(settings.IP,settings.PORT) # print(obj4.ip,obj4.port) obj4=MySQL.singleton() obj5=MySQL.singleton() obj6=MySQL.singleton() print(obj4 is obj5 is obj6)
以上是关于元类,__call__方法和单例模式的主要内容,如果未能解决你的问题,请参考以下文章