类的起源/metaclass

类的起源


  首先来看一段代码: ```python class Foo(object): pass obj = Foo() print(type(obj)) print(type(Foo)) ---------------------------------------------------- >>>: >>>: ```   上述代码中,obj 是通过 Foo 类实例化的对象。其实,不仅 obj 是一个对象,Foo类本身也是一个对象。因为在Python中一切事物都是对象。   那么从上述代码的执行结果可以看出,obj对象是通过执行Foo类的构造方法创建,那么Foo类对象应该也是通过执行type类的 构造方法 创建。   obj对象是Foo类的一个实例,Foo类对象是 type 类的一个实例。   综上,类的创建也就有两种形式。 ####**1.普通方法** ```python class Foo(object): def say_hi(self): print('hello world!') ``` ####**2.特殊方法(type)** ```python def say_hi(slef): print('hello world') Foo=type('Foo',(object,),{'say_hi':say_hi}) obj = Foo() obj.say_hi() --------------------------------------------- >>>:hello world --------------------------------------------- 用法:类名=type(类名,当前类的基类,类的成员) 也可以理解为动态的为一个类增加方法 ``` ###**  总结一下,一切皆是对象,对象起源为type(类的类) ,类是type实例化产生。**   既然如此,来看一看type中的描述: ```python class type(object): """ type(object_or_name, bases, dict) type(object) -> the object's type type(name, bases, dict) -> a new type """ def __init__(cls, what, bases=None, dict=None): # known special case of type.__init__ """ type(object_or_name, bases, dict) type(object) -> the object's type type(name, bases, dict) -> a new type # (copied from class doc) """ pass @staticmethod # known case of __new__ def __new__(*args, **kwargs): # real signature unknown """ Create and return a new object. See help(type) for accurate signature. """ pass ```   从上述代码中可以看出,type中的\__new__方法就是用来创建实例的。   既然如此,我们可以对写一个type的衍生类,并对\__new__进行重构,从而达到在实例化之前对类进行个性化设置。需要注意的是重构之后是没办法进行实例化的,需要继承父类的\__new__方法才能够完成实例化。   那么问题来了,python是如何知道当前类应当由谁来实例化创建呢?   实际上,类中还有一个属性\__metaclass__ 元类,该属性的作用就是用来表示该类由 谁 来实例化创建。 ```python class MyType(type): def __init__(self, what, bases=None, dict=None): super(MyType,self).__init__(what, bases, dict) def __call__(self,*args,**kwargs): print("Mytype __call__", *args, **kwargs) obj = self.__new__(self) print("obj ",obj,*args, **kwargs) print(self) self.__init__(obj,*args, **kwargs) return obj def __new__(cls,*args,**kwargs): print('Mytype __new__ :',*args,**kwargs) return type.__new__(cls,*args,**kwargs) #继承type的new方法

class Foo(object,metaclass=MyType):
def init(self,name):
self.name = name
print("Foo init")

def __new__(cls, *args, **kwargs):
    print("Foo __new__",cls, *args, **kwargs)
    return object.__new__(cls)

f = Foo("Tom")
print("f",f)
print("fname",f.name)

part1

:Mytype new : Foo (<class 'object'>,) {'module': 'main', 'qualname': 'Foo', 'init': <function Foo.init at 0x10374cbf8>, 'new': <function Foo.new at 0x10374cd08>}


part2

:Mytype call Tom
:Foo new <class 'main.Foo'>
:obj <main.Foo object at 0x103759550> Tom
:class 'main.Foo'>
:Foo init
:f <main.Foo object at 0x103759550>
:fname Tom

![](http://images2017.cnblogs.com/blog/1082150/201708/1082150-20170824153434543-237630177.png)




----------


###**具体详细解答:[metaclass](http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python),参考得票最高的解答**
posted @ 2017-08-24 15:35  在下不想说  阅读(145)  评论(0编辑  收藏  举报