V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
mainlong
V2EX  ›  Python

Python 中一切都是对象,那如果类是对象,那(什么)是类呢?

  •  
  •   mainlong · 2018-09-06 22:18:35 +08:00 · 5313 次点击
    这是一个创建于 2260 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目前只能理解,数据类型是类,如 int 类,str 类等。

    29 条回复    2018-09-08 15:09:05 +08:00
    lhx2008
        1
    lhx2008  
       2018-09-06 22:30:52 +08:00 via Android
    类是某一类对象的共有特征,"abc"是 string 类的对象
    CoderHugo
        2
    CoderHugo  
       2018-09-06 22:32:00 +08:00
    我实例化我自己
    yishengD
        3
    yishengD  
       2018-09-06 22:35:07 +08:00
    我觉得类不是对象,类是对象的描述。
    mimzy
        4
    mimzy  
       2018-09-06 22:42:36 +08:00 via Android   ❤️ 2
    类是 type 类的实例,type 是自身的实例。
    SpiderXiantang
        5
    SpiderXiantang  
       2018-09-06 22:47:12 +08:00
    type 吧
    troywinter
        6
    troywinter  
       2018-09-06 23:26:03 +08:00
    4 楼正解,类是 type 的实例,everything is an object, 包括模块也是对象。
    PythonAnswer
        7
    PythonAnswer  
       2018-09-06 23:28:19 +08:00   ❤️ 1
    >>> object
    <class 'object'>
    >>> object
    <class 'object'>
    >>> type(object)
    <class 'type'>
    >>> type
    <class 'type'>
    >>> type(type)
    <class 'type'>
    >>>
    d18
        8
    d18  
       2018-09-06 23:33:50 +08:00
    元类了解一下。
    bucky
        9
    bucky  
       2018-09-06 23:50:03 +08:00
    你抛开编程中的概念来思考会好一些,一个东西是类还是对象只是看的角度不同而已,比如模具相对于通过自己造出来的东西是类,而相对于造自己的模具来说就是对象了
    chroming
        10
    chroming  
       2018-09-07 00:15:39 +08:00
    刚学不用考虑一切皆对象这句话,不影响写代码
    zcjwxf
        11
    zcjwxf  
       2018-09-07 00:20:27 +08:00
    你管他是啥?多写点代码
    zxiso
        12
    zxiso  
       2018-09-07 00:25:14 +08:00 via Android
    类是对象的描述,对象是类的实例。
    innoink
        13
    innoink  
       2018-09-07 02:27:10 +08:00 via Android
    for 是对象吗?一切都是对象?
    fy
        14
    fy  
       2018-09-07 02:33:56 +08:00
    Python 类的类型也是类型,没什么元类这种东西。具体参考 CPython 源码。
    倒是 C 实现的类型和 Python 实现的类型本质上有区别,虽然表面上差不多,也能做继承。
    sammo
        15
    sammo  
       2018-09-07 03:22:11 +08:00
    和 “类” 对应的是 “类的实例”
    zhangpeter
        16
    zhangpeter  
       2018-09-07 07:39:58 +08:00
    zk123
        17
    zk123  
       2018-09-07 07:47:06 +08:00 via iPhone
    类就是不想说话
    Jex
        18
    Jex  
       2018-09-07 08:39:14 +08:00
    newmind
        19
    newmind  
       2018-09-07 09:20:53 +08:00
    type is type
    lxy42
        20
    lxy42  
       2018-09-07 09:41:30 +08:00
    在 Python 中一切都是对象,包括常见的基本数据类型、函数、方法、迭代器、生成器、模块等等。

    Python 对象模型:

    https://i.loli.net/2018/09/07/5b91d72d7b107.png
    lxy42
        21
    lxy42  
       2018-09-07 09:43:38 +08:00
    @fy #14 PyTypeObject 可以理解为元类吧。
    gansteed
        22
    gansteed  
       2018-09-07 10:04:40 +08:00
    《 Python 源码剖析》这本书可以看一下。此外可以了解一下 `metaclass` 这个概念。type 就是 metaclass。metaclass 是 class 的 class。class 是 metaclass 的实例。例如 str, list, int 是 type 的实例。

    class MyClass:
    pass

    这个 MyClass 默认继承 object,object 也是 type 的实例。my_instance = MyClass(),这里,MyClass 是 class。my_instance 是 MyClass 这个 class 实例化的结果。

    晕了么?😁

    参考资料:

    - 《 Python 源码剖析》: https://book.douban.com/subject/3117898/
    - "新式类": https://www.python.org/doc/newstyle/
    glacer
        23
    glacer  
       2018-09-07 10:17:02 +08:00 via iPhone
    在 Python 中,类是一种抽象的理念,在源码并不存在某个 class 的定义,因为类这个抽象理念在 Python 运行时中被实例化,Python 依靠运行时中的类实例来生成自己的对象实例,而不需要在代码中定义类的实现然后编译后在运行时载入内存。在 Python 的底层实现中,如 CPython,就对各个类的实现做了定位,比如 PyIntType,它在 Python 中对应的就是 int 类型,而各种类型实例对应 C 中的实现就是 PyIntobject。
    xpresslink
        24
    xpresslink  
       2018-09-07 11:37:07 +08:00
    Python 中所有东西都是对象,比较特殊的是:object 和 type 是 python 中的两个源对象,它们是互相依赖对方来定义,不能分割来说,
    就如同讨论“先有鸡还是现有蛋”,一样让人蛋疼。

    先介绍有两个黑魔法在后面要用到:
    obj.__bases__ 指这个对象的父类,就是说从谁继承来的。
    obj.__class__ 指这个对象的类型,类的类型是 type

    Python 的面向对象系统有两条线索。

    1.继承关系也就是父类和子类的关系( the subclass-superclass relationship ),以 object 为起点;

    所有对象的父类是 object,因此 object 是没有父类的。
    >>> object.__bases__
    ()

    type 也是 object 的子类
    >>> issubclass(type, object)
    True
    >>> type.__bases__
    (<class 'object'>,)

    2.类型和实例之间的关系( the type-instance relationship ),以 type 为起点。

    type 是自身的实例,或说 type (对象 object )的 class (类型 type )是 type
    >>> isinstance(type, type)
    True

    >>> type(type)
    <class 'type'>

    >>> type.__class__
    <class 'type'>

    就连 object 都是 type 的实例
    >>> isinstance(type, object)
    True


    总结一下:
    type 是一个比较特殊的类,这里引出另一概念元类,普通类实例化出来一个对象,但是元类实例化出来的是一个类,
    int、float、str、boolean、tuple、dict、set 等内置的数据类型其实也就是内置的类都是 type 实例。

    >>> isinstance(int, type)
    True

    >>> int.__class__
    <class 'type'>
    >>>


    object 是所有对象(包括类对象)的父类,int、float、str、boolean、tuple、dict、set 内置类都是 object 子类。
    >>> int.__bases__
    (<class 'object'>,)

    >>> isinstance(int, object)
    True
    PythonAnswer
        25
    PythonAnswer  
       2018-09-07 12:10:55 +08:00 via iPhone
    楼上总结的很好。

    但我总觉得 type 更早一些。谁来讲讲旧式类?当时 object 还没有强制使用。
    SimbaPeng
        26
    SimbaPeng  
       2018-09-07 13:44:41 +08:00
    Python 中只有 2 种对象,类和非类
    HelloAmadeus
        27
    HelloAmadeus  
       2018-09-07 21:14:02 +08:00
    看点 python 源码实现就对"一切都是对象" 这种模糊的描述更清晰了. 举一个简单的例子两个 int 相加, 伪代码如下:

    PyObject * Interger_Add(PyObject* left, PyObject* right) {
    PyIntObject* int_left = (PyIntObject*) left;
    PyIntObject* int_right = (PyIntObject*) left;
    PyIntObject* int_new = (PyIntObject*) Py_GC_MALLOC(&PyIntObject);



    }
    HelloAmadeus
        28
    HelloAmadeus  
       2018-09-07 21:49:22 +08:00
    看点 python 源码实现就对"一切都是对象" 这种模糊的描述更清晰了. 举一个简单的例子如两个 int 相加, 伪代码如下:

    PyObject * Interger_Add(PyObject* left, PyObject* right) {

    PyIntObject* int_left = (PyIntObject*) left;
    PyIntObject* int_right = (PyIntObject*) left;
    PyIntObject* int_new = (PyIntObject*) Py_GC_MALLOC(&PyIntObject); # 在 malloc 之后做一些如添加引用计数等工作

    int_new->ob_data = int_left->ob_data + int_right->ob_data; # ob_data 为 c long 类型
    return (PyObject*) int_new;
    }

    你看, 一个 两个 int 型相加, 参数传进来的是 PyObject , 返回的是 PyObject. 一切都是对象是不是更好理解了.
    还有 Python 的 module 是怎么也是对象. 也有类似这样的函数, PyObjcet* model_reload(PyObject* module);
    你看重载 module, 参数传进来的都是 PyObject, 返回的也是 PyObject, 一切都是对象是不是更清晰了?

    如果不从 Python 源码来理解的话, 你就要区分 object 这个关键词 python 与 c++和 java 中的区别, object 在 c++和 java 中的概念更像是 python 中 实例(instance) 的概念.

    在面向对象编程概念里, 类是抽象数据和与这些抽象数据相关操作的集合, 对象是类的实例, 也就是具体数据和构建在这些具体数据上的集合. 这个概念与 python 中一切都是对象是完全不在一个层面上的比较.

    面向对象是一种抽象, 他与语言是无关的, 任何语言都能实现面向对象中的至少一部分想法. 而"一切都是对象" 这句话描述的不是抽象, 而是具体的实现.

    python 通过 PyObject 实现了面向对象这个抽象的思想. 所以在一些地方借鉴了思想的关键字. 如 class, object. 但是这些词并不是严格对应面向对象的概念, 因为 python 是多范式的编程语言.

    所以把"一切都是对象"中的对象和面向对象编程中的对象 这两个对象区分开, 才能理解 python 中一切都是对象, 这个概念.

    P.S. v2 的编辑器真是垃圾.
    fy
        29
    fy  
       2018-09-08 15:09:05 +08:00
    @lxy42 #21 但 CPython 实现上并没有说 Type 这个 class 比其他 class 高一档或者有很多的特殊之处。metaclass 这个概念其实更多的是一种 class hack 或者是 injection
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5434 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 37ms · UTC 06:49 · PVG 14:49 · LAX 22:49 · JFK 01:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.