python面向对象整理(二):type和object

一、type和object
先来看js:
js除了值类型都是对象。一切(引用类型)都是对象。
对象的定义:属性的集合。而所有对象都是由函数Object/Function创建的。 但是要注意,函数也是对象,函数只不过是一类特殊的能创造对象的对象(搁在python里就是类对象)。
每个对象都有一个__proto__,指向创建它的函数的prototype。Function创建一切函数,包括他自己,所以他的__proto__指向自身的prototype。(Function其实类似于python中的type)
(特殊例外:Object.prototype.__proto__指向null)

函数:带有[[Construct]]内部方法的对象能创造新的对象。
函数是对象的一种。所以函数也是属性的集合。函数名是指向对象的指针。
Function创建一切函数,包括他自己。
每个函数都有一个prototype,这个prototype都是对象(属性的集合),这个prototype呢是由Object创造的。
注意:Object()是函数

在这里插入图片描述
这个图呢分左中右三列,左边和右边都是普通对象。中间一列是函数对象。
原型给js中的继承带来了灵活性。

再来看python:在这里插入图片描述
要区分清楚继承和实例化是OO中两个不同的概念。
python中所有对象分为类对象和实例对象。python中的类也是对象(一切都是对象)。类对象和普通对象的区别就是类对象可以创建普通对象。
所有的类对象都是由type创造(实例化)出来的,包括type
所有的类都是object的子类,包括type。

在这里插入图片描述
这图是在解释器中python的type和object实现。PyType_Type就是type类,PyBaseObject_Type是object类。
数据结构中的ob_type指向每个类的类型(type函数的结果),而tp_bases指向父类。
PyXxx_Type,可以看成是继承自Object的类对象Xxx。那么type(Xxx)=type。
PyXxx_Object就是Xxx的实例对象。

如何实现:
在初始化的时候,给type和object分别分配一块内存,然后把各种指针指向正确的位置。这时,一个完整的对象系统就建立好了。所以type和object是同时存在或者不存在的。这是一个称为“自举”(bootstrap)的过程。

看来不同的编程语言在实现时也有一些相似之处,还不清楚为什么他们要这么设计,可能是为了区分开实例化和继承。

顺便说一下,字典dict是个非常重要的数据结构,js中的object当初就是模仿python中的dict实现的。而python中的dict由于使用广泛而内置在解释器中。

进一步阅读:
Python 的 type 和 object 之间是怎么一种关系?

二、元类:
我们可以通过type函数创造一个元类
type就是创建类对象的类。str和int都是从type生成的类
深刻理解Python中的元类(metaclass)

MyShinyClass = type('MyShinyClass', (object,), {})  # 返回一个类对象 {}里为类的值,函数名等

builtins.py:
class type(object):
    """
    type(object_or_name, bases, dict)
    type(object) -> the object's type
    type(name, bases, dict) -> a new type
    """
        @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

典型的元类写法:

class UpperAttrMetaclass(type):
    def __new__(cls, name, bases, dct):
        attrs = ((name, value) for name, value in dct.items() if not name.startswith('__'))
        uppercase_attr = dict((name.upper(), value) for name, value in attrs)
        return super(UpperAttrMetaclass, cls).__new__(cls, name, bases, uppercase_attr)

元类的实现细节:

{'__module__': 'BlogSpider.items', '__qualname__': 'BlogspiderItem', 'title': {}, 'source': {}, 'content': {}}

最终返回的class名字由attrs里的__module__ 和__qualname__ 决定
不管name怎样,上图的attrs会返回类

<class 'BlogSpider.items.BlogspiderItem'>

元类的主要目的就是一个类拦截器,当创建类时能够自动地改变类。

可以使用__new__, __init__以及__call__这样的特殊方法。它们能帮你处理不同的任务。
(有时候我们使用__new__而不是__init__这是因为能达到__init__不能完成的任务)
元类的主要用途是创建API。一个典型的例子是Django ORM。
文末提到的元类在Django框架中的使用值得深入挖掘一下,正好是由于前两天看django的表单代码才想研究元类的

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值