前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python源码阅读笔记之几个值得注意的点

python源码阅读笔记之几个值得注意的点

作者头像
哒呵呵
发布2018-08-06 15:38:28
5100
发布2018-08-06 15:38:28
举报
文章被收录于专栏:鸿的学习笔记
代码语言:javascript
复制
在扯函数的运行机制之前,先看看python虚拟机的运行。
py文件会先编译成pyc文件,生成字节码(ceval.c),再执行。
名字空间的概念:类,函数,module都有自己独有的名字空间,python在查找变量值时,会查找的是名字空间里的变量值。
在动态语言里,名字是能够找到其对应东西的唯一途径。
在python里,赋值语句的概念是创建一个对象obj,将这个对象赋值给一个名字,是不是很熟悉。
对的,这也就是为啥python会单独对字符串的dict对象做优化了。
一个对象的名字空间中的所有名字都称为对象的属性,这还牵扯到属性引用。在一个module内部都维护着自己的作用域。
与动态不符的一点是,一个约束是否其作用取决于源程序的文本,也就是说文本的位置决定着这个约束是否起作用。
作用域嵌套:由一个赋值语句引进的名字在这个赋值语句所在的作用域是可见的,而且在其嵌套的每个作用域也可见,
除非它被嵌套于内部,引进同样名字的另一条赋值语句所遮蔽。
python查找变量也是这么查找的LGB,module的作用域-global,函数的是-local,最顶层的作用域-builtin。

再简单聊聊python的一般表达式和条件语句:
1.在python中数值运算不是简单的数值运算,会牵扯到很多对象的检查。如下所示:
            w = POP();
            v = TOP();
            if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
                /* INLINE: int + int */
                register long a, b, i;
                a = PyInt_AS_LONG(v);
                b = PyInt_AS_LONG(w);
                /* cast to avoid undefined behaviour
                   on overflow */
                i = (long)((unsigned long)a + b);
                if ((i^a) < 0 && (i^b) < 0)
                    goto slow_add;
                x = PyInt_FromLong(i);
            }
            else if (PyString_CheckExact(v) &&
                     PyString_CheckExact(w)) {
                x = string_concatenate(v, w, f, next_instr);
                /* string_concatenate consumed the ref to v */
                goto skip_decref_vx;
            }
            else {
              slow_add:
                x = PyNumber_Add(v, w);
            }
            Py_DECREF(v);
          skip_decref_vx:
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) continue;
            break;
 
不简单吧
2.if中的比较操作:
            w = POP();
            v = TOP();
            if (PyInt_CheckExact(w) && PyInt_CheckExact(v)) {
                /* INLINE: cmp(int, int) */
                register long a, b;
                register int res;
                a = PyInt_AS_LONG(v);
                b = PyInt_AS_LONG(w);
                switch (oparg) {
                case PyCmp_LT: res = a <  b; break;
                case PyCmp_LE: res = a <= b; break;
                case PyCmp_EQ: res = a == b; break;
                case PyCmp_NE: res = a != b; break;
                case PyCmp_GT: res = a >  b; break;
                case PyCmp_GE: res = a >= b; break;
                case PyCmp_IS: res = v == w; break;
                case PyCmp_IS_NOT: res = v != w; break;
                default: goto slow_compare;
                }
                x = res ? Py_True : Py_False;
                Py_INCREF(x);
            }
            else {
              slow_compare:
                x = cmp_outcome(oparg, v, w);
            }
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x == NULL) break;
            PREDICT(POP_JUMP_IF_FALSE);
            PREDICT(POP_JUMP_IF_TRUE);
            continue;
在牵扯到int时,比较的很快,但是其他操作,让我们看看cmp_outcome
static PyObject *
cmp_outcome(int op, register PyObject *v, register PyObject *w)
{
    int res = 0;
    switch (op) {
    case PyCmp_IS:
        res = (v == w);
        break;
    case PyCmp_IS_NOT:
        res = (v != w);
        break;
    case PyCmp_IN:
        res = PySequence_Contains(w, v);
        if (res < 0)
            return NULL;
        break;
    case PyCmp_NOT_IN:
        res = PySequence_Contains(w, v);
        if (res < 0)
            return NULL;
        res = !res;
        break;
    case PyCmp_EXC_MATCH:
        if (PyTuple_Check(w)) {
            Py_ssize_t i, length;
            length = PyTuple_Size(w);
            for (i = 0; i < length; i += 1) {
                PyObject *exc = PyTuple_GET_ITEM(w, i);
                if (PyString_Check(exc)) {
                    int ret_val;
                    ret_val = PyErr_WarnEx(
                        PyExc_DeprecationWarning,
                        "catching of string "
                        "exceptions is deprecated", 1);
                    if (ret_val < 0)
                        return NULL;
                }
                else if (Py_Py3kWarningFlag  &&
                         !PyTuple_Check(exc) &&
                         !Py3kExceptionClass_Check(exc))
                {
                    int ret_val;
                    ret_val = PyErr_WarnEx(
                        PyExc_DeprecationWarning,
                        CANNOT_CATCH_MSG, 1);
                    if (ret_val < 0)
                        return NULL;
                }
            }
        }
        else {
            if (PyString_Check(w)) {
                int ret_val;
                ret_val = PyErr_WarnEx(
                                PyExc_DeprecationWarning,
                                "catching of string "
                                "exceptions is deprecated", 1);
                if (ret_val < 0)
                    return NULL;
            }
            else if (Py_Py3kWarningFlag  &&
                     !PyTuple_Check(w) &&
                     !Py3kExceptionClass_Check(w))
            {
                int ret_val;
                ret_val = PyErr_WarnEx(
                    PyExc_DeprecationWarning,
                    CANNOT_CATCH_MSG, 1);
                if (ret_val < 0)
                    return NULL;
            }
        }
        res = PyErr_GivenExceptionMatches(v, w);
        break;
    default:
        return PyObject_RichCompare(v, w, op);
    }
    v = res ? Py_True : Py_False;
    Py_INCREF(v);
    return v;
}

是不是感觉很复杂,一步步检查,比如tuple,list等集合操作都包括在里面了。
字节码的概念:在python2.7的opcode.h的文件中存储着一百多条字节码,可通过dis包查看


本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-07-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 鸿的学习笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档