object是类的基类,type是类的元类
type
类的类
class Foo:
pass
print(type(Foo))
# <class 'type'>
我们可以通过type来实例一个类,一个类创建的过程就是类的类被调用的过程
def fn(self, name='world'): # 假如我们有一个函数叫fn
print('Hello, %s.' % name)
Hello = type('Hello', (object,), dict(say_hello=fn)) # 第一个参数是类名字,第二个参数是父类的集合,
# 第三个参数是类的方法和属性的字典,键是属性或方法名,
# 上面的写法就相当于
class Hello():
def say_hello(self, name='world'):
print('Hello, %s.' % name)
上面的类并没有声明自己的元类,默认就是type,
class Moo(type):
pass
class Aoo():
pass
class Foo(metaclass=Moo):
pass
print(type(Moo)) # <class 'type'>
print(type(Aoo)) # <class 'type'>
print(type(Foo)) # <class '__main__.Moo'>
另外还有很重要的一点,一个类继承了指定元类的类,那么这个类的元类就会是继承类的元类
定义了metaclass的类的子类
在python2中元类的定义时作为类的属性
class Moo(type):
pass
class Foo():
__metaclass__ = Moo
当一个类继承了Foo时,会向上查找到__metaclass__属性,也就会由__metaclass__指定的类来实例类.
在python3中虽然metaclass是由参数传递的,但他同样拥有这样的性质,一个类继承了指定metaclass的类,都会有指定的metaclass产生.
class a(type):
def __init__(self,*args,**kwarsg):
print("造了个类")
type.__init__(self,*args,**kwarsg)
class c(metaclass=a): # 造了个类
pass
class d(c): # 造了个类
pass
class b(d): # 造了个类
pass
我们也可以通过继承type来重写元类来控制类的产生
自定义的元类也要接收三个参数
同时也要了解一下类的一些方法:
- __new__: 对象的创建,是一个静态方法。第一个參数是cls。(想想也是,不可能是self,对象还没创建,哪来的self)
- __init__ : 对象的初始化, 是一个实例方法,第一个參数是self。
- __call__ : 实例可call。注意不是类,是实例。
先有创建,才有初始化。即先__new__,而后__init__。
class Aoo():
def __call__(self):
return "haha"
a = Aoo()
print(a())
# 哈哈哈
一个简单实例
class a(type):
def __new__(cls, *args, **kwargs):
print(args) # ('b', (), {'__module__': '__main__', '__qualname__': 'b'})
print(kwargs) # {}
return type.__new__(cls, *args, **kwargs)
def __init__(cls, name, bases, attrs):
type.__init__(cls, name, bases, attrs)
print("造了个类")
def __call__(cls):
type.__call__(cls)
print("实例了个类")
class b(metaclass=a): # 造了个类
pass
b() # 实例了个类
根据__call__实现单例模式:
既然类是元类的实例,那么类被实例化时就就执行了元类的__call__方法,我们可以根据这个来实现单例模式的类
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs): # 他的实例化出来的类实例化时调用了这个方法,
if cls not in cls._instances:
# 如果这个来没有实例化对象,就去执行type的__call__方法,并且把实例存储在cls._instances中
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls] # 返回实例
class MyClass(metaclass=Singleton):
pass
a = MyClass()
还可以
MyClass = Singleton("MyClass",(object,),{"name":"pa"})
a = MyClass()
b = MyClass()
print(a is b)
# True
更多方法我也不会