最初博主是希望在python当中创建一个单列模式的类,因为python当中不像java和php当中有权限修饰符(private),所以实现起来要绕一点。
网上找了一下python实现单列模式,类似的大概有这种方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
class singleton(type): """ 实现单列模式的元类 总之,metaclass的主要任务是: 拦截类, 修改类, 返回类 """ def __init__(cls,classname,parrentstuple,attrdict): """ """ super(SigleInstance,cls).__init__(classname,parrentstuple,attrdict) cls._instance = None def __call__(self,*args,**kargs): """ """ if self._instance: return self._instance else: self._instance = super(SigleInstance,self).__call__(*args,**kargs) return self._instance |
这就是单列的元类,我把它小写了,因为type也是小写的。然后呢,在即将要实现单列的class当中这样写:
1 2 3 4 |
class Earth(object): __metaclass__ = singleton def __init__(self,a,b): pass |
这样每次 创建一个 Earth()取得的始终都应该是一个实例。
关于__metaclass__ 和type这个东西可以参考深入理解Python中的元类(metaclass)。这篇文章解决了我大部分的疑惑,但是我还是没有搞清楚的是:
当__metaclass__是一个类的时候,metaclass是怎样去创建一个类的?
在这之前首先说明一下:
一。python当中一切都是对象,而对象都是由类创建,这里为了区分概念,我们不妨换一种说法:实例都是由模板创建的。
二。那么什么又是对象的type呢?type就是类型的意思。如果您对java稍微有一点了解。你会有这样的认识:
1 2 3 4 5 |
/** * language是一个String类型的变量,值为"python" * 在java当中,如果 Integer language = "python"就是错误的 */ String language = "python"; |
由于python是一门动态语言,所以在写代码的时候不必声明变量的类型,也不可能完全确定这个变量是什么类型,除非对自己代码的逻辑以及流程非常清楚,另外python在运行当中变量的类型是可以更改的。但是不能确定变量的类型,不代表就没有类型啊。python当中的变量一样是有类型的。那么怎么来看变量的类型呢?答案是使用type。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
language = "python" print type(language) # python2.7中输出:<type 'str'> # ipython 输出 str number = 2 print type(number) #输出:<type 'int'> class A(object): pass a = A() print type(a) #输出:<type '__main__.A'> |
上面段代码分别用type查看到了各个变量的类型。根据(一)【python当中一切都是对象,而对象都是由类创建,这里为了区分概念,我们不妨换一种说法:实例都是由模板创建的】我们可不可以这样说呢:language是str的实例,str是language实例的模板。因此type(a_var)的输出就是a_var这个实例的模板。所以我们看到 type(a)的输出是,也就是说 a实例的模板是A。
class A的模板是什么呢?
1 2 |
print type(A) #输出:<type 'type'> |
也就是说,一个类的模板的type,类是type的一个实例,tpye实例化了一个对象,这个对象就是class。所以在python的世界里,一切都是对象,类也是对象。
那么有意思的地方来了,type的模板是什么呢,也就是,type的type是什么呢?
1 2 |
print type(type) # 输出<type 'type'> |
是不是很有意思,type的type是type。很绕,换成大白话说:type的模板是type自己。那么是不是就可以这样说呢?TYPE(type,为了区分说明,故意大写)是type的模板,type是TYPE的实例,因此说明type是一个实例;而TYPE是一个模板,也就是一个类!,因为TYPE==type,那么可以得出结论: