读以下代码:

1
2
3
4
5
6
class Foo(object):
 
    def __init__(self):
        pass
 
obj = Foo()   # obj是通过Foo类实例化的对象

上述代码中,obj 是通过 Foo 类实例化的对象,其实,不仅 obj 是一个对象,Foo类本身也是一个对象,因为在Python中一切事物都是对象

如果按照一切事物都是对象的理论:obj对象是通过执行Foo类的构造方法创建,那么Foo类对象应该也是通过执行某个类的 构造方法 创建。

1
2
print type(obj) # 输出:<class '__main__.Foo'>     表示,obj 对象由Foo类创建
print type(Foo) # 输出:<type 'type'>              表示,Foo类对象由 type 类创建

所以,obj对象是Foo类的一个实例Foo类对象是 type 类的一个实例,即:Foo类对象 是通过type类的构造方法创建。

那么,创建类就可以有两种方式:

a). 普通方式

1
2
3
4
class Foo(object):
 
    def func(self):
        print 'hello wupeiqi'

b).特殊方式(type类的构造函数)

1
2
3
4
5
6
7
def func(self):
    print 'hello wupeiqi'
 
Foo = type('Foo',(object,), {'func': func})
#type第一个参数:类名
#type第二个参数:当前类的基类
#type第三个参数:类的成员

==》 类 是由 type 类实例化产生

那么问题来了,类默认是由 type 类实例化产生,type类中如何实现的创建类?类又是如何创建对象?

答:类中有一个属性 __metaclass__,其用来表示该类由 谁 来实例化创建,所以,我们可以为 __metaclass__ 设置一个type类的派生类,从而查看 类 创建的过程。

 

Python中一切事物都是对象之类创建的本质

 

class MyType(type):

def __init__(self, what, bases=None, dict=None):
super(MyType, self).__init__(what, bases, dict)

def __call__(self, *args, **kwargs):
obj = self.__new__(self, *args, **kwargs)

self.__init__(obj)

class Foo(object):

__metaclass__ = MyType

def __init__(self, name):
self.name = name

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

# 第一阶段:解释器从上到下执行代码创建Foo类
# 第二阶段:通过Foo类创建obj对象
obj = Foo()

Python中一切事物都是对象之类创建的本质
#!/usr/bin/env python
# -*- coding: utf-8 -*-

class MyType(type):
def __call__(cls, *args, **kwargs):
#cls是类class属性
obj = cls.__new__(cls,*args,**kwargs)
#在执行type类的new方法的时候 此处已经创建对象
print("=====")
print(cls)
#__init__方法只是初始化而已 不写也可以
        obj.__init__(*args,**kwargs)
return obj

class Foo(metaclass=MyType):
def __init__(self,name):
print("------")
self.name=name

def f1(self):
print(self.name)
#解释器解释
#1,遇到class Foo,执行type__init__方法
#2Typeinit的方法里面做什么呢?不知道 C语言写的 无法修改
obj = Foo(123)//执行type的call方法
print(obj)
print(obj.name)
#3,执行Type__call__方法
# 执行Foo类的__new__方法
# 执行Foo类的__init__方法

C:\Python35\python.exe D:/py_django/test/a2.py
=====
<class '__main__.Foo'>
------
<__main__.Foo object at 0x0000000000714160>
123

相关文章:

  • 2021-07-11
  • 2021-11-23
  • 2021-08-03
  • 2021-08-16
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-06-30
  • 2022-12-23
  • 2021-11-18
  • 2021-05-20
  • 2022-01-30
  • 2022-12-23
  • 2021-08-04
相关资源
相似解决方案