元类,__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)

 

posted @ 2018-04-17 23:22  Ryansuperwa  阅读(249)  评论(0编辑  收藏  举报