收集整理了一份《2024年最新Python全套学习资料》免费送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Python知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来
如果你需要这些资料,可以添加V无偿获取:hxbc188 (备注666)
正文
In [21]: def f(x):
…: y = 3
…: def g():
…: return y + 1
…: return g()
…:
In [22]: f.func_code.co_cellvars
Out[22]: (‘y’,)
In [23]: f.func_code.co_consts[2].co_freevars
Out[23]: (‘y’,)
与存储元组的其他几个代码对象属性一样,处理这些变量的字节码使用元组的索引。例如,y上面第 2 行的赋值被编译成一个STORE_DEREF带有参数 0 的操作码,表示它位于单元变量y中的位置 0,第y4 行的读取变成LOAD_DEREF带有参数 0 的操作码。DEREF操作码用于单元变量和freevars 和索引实际上是两个 ( co_cellvars + co_freevars) 的串联,所以如果一个函数有 cellvars(a, b)和 freevars (c, d),LOAD_DEREF2 将加载的值c和LOAD_DEREF1 将加载b。在 cellvar 和 freevar 中,名称按字母顺序列出。
我不熟悉这两个字段在运行时如何用于将信息从一个功能范围传递到另一个功能范围。
co_code,这是二进制格式的实际字节码,存储为普通的 Python 字符串。如上所示,它是VM的指令列表。函数从第一条指令开始执行,在遇到RETURN_VALUE指令时停止。在此答案的其他地方讨论了一些字节码,所有字节码都记录在dis模块文档,但我不会在这里讨论所有的说明。
字符串中的编码在co_code每条指令中使用可变数量的字节。每条指令都包含一个opcode ,它指示 VM 要执行的操作,加上一个可选参数,它始终是一个整数。操作码是一个单字节整数,因此可能有 256 个不同的操作码,尽管其中许多当前未使用。每个操作码都有一个名称,该名称显示在dis输出中(参见上面的几个示例)并在opcode标准库模块中定义。
所有整数值低于称为HAVE_ARGUMENT(Python 2.7 上为 90)的截止值的操作码都没有参数,因此它们的指令只占用一个字节。接受参数的操作码占用三个字节,其中第二个和第三个字节以小端顺序存储参数。如果参数太大而无法容纳这两个字节(即,它大于216= 65536),使用了一个特殊的操作码EXTENDED_ARG。例如,如果您想在函数中加载第 65537 个单元格变量(为什么要这样做呢?),您首先有一个EXTENDED_ARG带有参数 1 的指令,然后是LOAD_DEREF带有参数 1 的指令,表明您需要加载元素1 * 65536 + 1 = 65537.
co_consts。这是函数中使用的所有常量的元组,如整数、字符串和布尔值。它由LOAD_CONST操作码使用,它接受一个参数,该参数指示co_consts要从中加载的元组中的索引。例如,f下面是上面定义的函数的常量co_cellvars:
In [34]: print f.func_code.co_consts
(None, 3, <code object g at 0xf6796800, file “”, line 3>)
元组中的第二个元素是3,因此赋值代码y = 3包含指令LOAD_CONST1,指示索引 1 处的常量应放入堆栈。同样,LOAD_CONST2 在创建嵌套函数时加载代码g。
函数代码对象中的第一个co_consts元素始终是函数的文档字符串,可能是None(就像这里一样)。否则,常量大多按照它们在字节码中首次使用的顺序排列,但 VM 不需要这样做,而且 CPython 的窥孔优化器在生成字节码后运行,有时会做出不遵守此顺序的更改。
co_filename。这是在其中创建代码的文件的名称。
co_firstlineno。生成代码对象的 Python 代码开头的 1 索引行号。与 结合使用co_lnotab,用于计算异常回溯等位置的行信息。
co_flags。这是一个整数,它结合了许多关于函数的布尔标志。它没有完全记录,但标志包括(使用inspect模块中定义的名称):
-
CO_OPTIMIZED
: 表示该函数是在启用 Python 优化的情况下编译的;我相信这只是意味着删除文档字符串和断言。 -
CO_NEWLOCALS
:为除模块之外的所有代码对象设置;我猜这是对 CPython 的早期更改的残余。 -
CO_VARARGS
: 该函数采用 *args。 -
CO_VARKEYWORDS
: 该函数需要 **kwargs。 -
CO_NESTED
: 该函数嵌套在另一个函数中。 -
CO_GENERATOR
: 该函数是一个生成器函数。 -
CO_NOFREE
: 如果函数没有单元格或自由变量,则设置。
co_lnotab。这意味着行号表,并存储字节码指令到行号的压缩映射。它是一串二进制数据,其中每两个字节是一对(增加co_code字符串中的偏移量,增加 Python 行号)。第一个从 0 开始,第二个从 的值开始co_firstlineno。这是一个例子:
In [39]: def f(x):
…: x = 3
…: y = 4
…:
In [40]: f.func_code.co_lnotab
Out[40]: ‘\x00\x01\x06\x01’
In [41]: dis.dis(f)
2 0 LOAD_CONST 1 (3)
3 STORE_FAST 0 (x)
3 6 LOAD_CONST 2 (4)
9 STORE_FAST 1 (y)
12 LOAD_CONST 0 (None)
15 RETURN_VALUE
在这个函数中,代表六个字节的前两条指令来自函数代码的第一行,其余的来自第二行。co_lnotab可以更易读地呈现为 (0, 1), (6, 1) 。第一行表示我们应该将字节码偏移量加0,行号偏移量加1(第一行号是def行,但没有字节码直接对应)。然后第二行告诉我们将字节码偏移量增加 6,行号偏移量增加 1,这对应于接下来的 6 个字节在我们刚刚通过的行的事实。然后其余的代码隐含在我们现在到达的那一行。这在lnotab_notes.txt中有更详细的解释在 Python 源代码中。
在实践中,Python 有时会生成条目略多于所需条目的 lnotab。例如,由生成器表达式(例如(f(x) for x in lst))创建的代码对象总是有一个非空的 lnotab,即使所有代码都在第一行。
co_name。这是与代码对象相关联的对象(例如函数)的名称。
同名。在代码对象中用作属性、全局变量名称和导入名称的字符串元组。使用这些名称之一的操作码(例如,LOAD_ATTR)将这个元组的整数索引作为参数。这些是按第一次使用的顺序。
co_names。函数中局部变量的数量。据我所知,这只是co_varnames. 这可能是为了决定在调用函数时为局部变量分配多少空间。
最后
不知道你们用的什么环境,我一般都是用的Python3.6环境和pycharm解释器,没有软件,或者没有资料,没人解答问题,都可以免费领取(包括今天的代码),过几天我还会做个视频教程出来,有需要也可以领取~
给大家准备的学习资料包括但不限于:
Python 环境、pycharm编辑器/永久激活/翻译插件
python 零基础视频教程
Python 界面开发实战教程
Python 爬虫实战教程
Python 数据分析实战教程
python 游戏开发实战教程
Python 电子书100本
Python 学习路线规划
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
如果你需要这些资料,可以添加V无偿获取:hxbc188 (备注666)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
研究,那么很难做到真正的技术提升。**
如果你需要这些资料,可以添加V无偿获取:hxbc188 (备注666)
[外链图片转存中…(img-eCd7jjfX-1713842275807)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!