草庐IT

python - 已编译脚本的字节码因编译方式而异

coder 2023-08-19 原文

<分区>

当天早些时候,我对文档字符串和 dis 模块进行了大量试验,遇到了一些我似乎无法找到答案的问题。

首先,我创建一个包含以下内容的文件 test.py:

def foo():
    pass

只有这个,没有别的。

然后我打开了一个解释器来观察程序的字节码。你可以这样得到它:

code = compile(open('test.py').read(), '', 'exec')

第一个参数是字符串形式的代码,第二个参数用于调试目的(留空也可以),第三个参数是模式。我已经尝试了 singleexec。结果是一样的。

在此之后,您可以使用dis 反编译字节码。

>>> import dis
>>> dis.dis(code)

字节码输出是这样的:

 1           0 LOAD_CONST               0 (<code object foo at 0x10a25e8b0, file "", line 1>)
              3 MAKE_FUNCTION            0
              6 STORE_NAME               0 (foo)
              9 LOAD_CONST               1 (None)
             12 RETURN_VALUE        

合理,对于这么简单的脚本。这也是有道理的。

然后我尝试像这样通过命令行编译它:

$ python -m py_compile test.py

这导致字节码生成并放置在 test.pyc 文件中。内容可以再次反汇编:

>>> import dis
>>> dis.dis(open('test.pyc').read())

这是输出:

>>    0 ROT_THREE      
      1 <243>            2573
>>    4 <157>           19800
>>    7 BUILD_CLASS    
      8 DUP_TOPX            0
     11 STOP_CODE      
     12 STOP_CODE      
>>   13 STOP_CODE      
     14 STOP_CODE      
     15 STOP_CODE      
     16 STOP_CODE      
     17 POP_TOP        
     18 STOP_CODE      
     19 STOP_CODE      
     20 STOP_CODE      
     21 BINARY_AND     
     22 STOP_CODE      
     23 STOP_CODE      
     24 STOP_CODE      
     25 POP_JUMP_IF_TRUE    13
     28 STOP_CODE      
     29 STOP_CODE      
     30 LOAD_CONST          0 (0)
     33 MAKE_FUNCTION       0
     36 STORE_NAME          0 (0)
     39 LOAD_CONST          1 (1)
     42 RETURN_VALUE   
     43 STORE_SLICE+0  
     44 ROT_TWO        
     45 STOP_CODE      
     46 STOP_CODE      
     47 STOP_CODE      
     48 DUP_TOPX            0
     51 STOP_CODE      
     52 STOP_CODE      
     53 STOP_CODE      
     54 STOP_CODE      
     55 STOP_CODE      
     56 STOP_CODE      
     57 POP_TOP        
     58 STOP_CODE      
     59 STOP_CODE      
     60 STOP_CODE      
     61 INPLACE_POWER  
     62 STOP_CODE      
     63 STOP_CODE      
     64 STOP_CODE      
     65 POP_JUMP_IF_TRUE     4
     68 STOP_CODE      
     69 STOP_CODE      
     70 LOAD_CONST          0 (0)
     73 RETURN_VALUE   
     74 STORE_SLICE+0  
     75 POP_TOP        
     76 STOP_CODE      
     77 STOP_CODE      
     78 STOP_CODE      
     79 INPLACE_XOR    
     80 STORE_SLICE+0  
     81 STOP_CODE      
     82 STOP_CODE      
     83 STOP_CODE      
     84 STOP_CODE      
     85 STORE_SLICE+0  
     86 STOP_CODE      
     87 STOP_CODE      
     88 STOP_CODE      
     89 STOP_CODE      
     90 STORE_SLICE+0  
     91 STOP_CODE      
     92 STOP_CODE      
     93 STOP_CODE      
     94 STOP_CODE      
     95 STORE_SLICE+0  
     96 STOP_CODE      
     97 STOP_CODE      
     98 STOP_CODE      
     99 STOP_CODE      
    100 POP_JUMP_IF_TRUE     7
    103 STOP_CODE      
    104 STOP_CODE      
    105 LOAD_GLOBAL     29541 (29541)
    108 LOAD_GLOBAL     28718 (28718)
    111 SETUP_EXCEPT      884 (to 998)
    114 STOP_CODE      
    115 STOP_CODE      
    116 STOP_CODE      
    117 BUILD_TUPLE     28527
    120 POP_TOP        
    121 STOP_CODE      
    122 STOP_CODE      
    123 STOP_CODE      
    124 POP_JUMP_IF_TRUE     2
    127 STOP_CODE      
    128 STOP_CODE      
    129 STOP_CODE      
    130 POP_TOP        
    131 INPLACE_XOR    
    132 STORE_SLICE+0  
    133 POP_TOP        
    134 STOP_CODE      
    135 STOP_CODE      
    136 STOP_CODE      
    137 LOAD_LOCALS    
    138 STOP_CODE      
    139 STOP_CODE      
    140 STOP_CODE      
    141 STOP_CODE      
    142 STORE_SLICE+0  
    143 STOP_CODE      
    144 STOP_CODE      
    145 STOP_CODE      
    146 STOP_CODE      
    147 STORE_SLICE+0  
    148 STOP_CODE      
    149 STOP_CODE      
    150 STOP_CODE      
    151 STOP_CODE      
    152 STORE_SLICE+0  
    153 STOP_CODE      
    154 STOP_CODE      
    155 STOP_CODE      
    156 STOP_CODE      
    157 POP_JUMP_IF_TRUE     7
    160 STOP_CODE      
    161 STOP_CODE      
    162 LOAD_GLOBAL     29541 (29541)
    165 LOAD_GLOBAL     28718 (28718)
    168 SETUP_EXCEPT     2164 (to 2335)
    171 STOP_CODE      
    172 STOP_CODE      
    173 STOP_CODE      
    174 STORE_SUBSCR   
    175 IMPORT_FROM     25711 (25711)
    178 <117>           25964
    181 BINARY_LSHIFT  
    182 POP_TOP        
    183 STOP_CODE      
    184 STOP_CODE      
    185 STOP_CODE      
    186 POP_JUMP_IF_TRUE     0
    189 STOP_CODE      
    190 STOP_CODE      

差异是惊人的。为什么字节码会因编译方式的不同而出现如此鲜明的对比?

有关python - 已编译脚本的字节码因编译方式而异的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  3. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  4. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  5. ruby-on-rails - 独立 ruby​​ 脚本的配置文件 - 2

    我有一个在Linux服务器上运行的ruby​​脚本。它不使用rails或任何东西。它基本上是一个命令行ruby​​脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg

  6. ruby-on-rails - 正确的 Rails 2.1 做事方式 - 2

    question的一些答案关于redirect_to让我想到了其他一些问题。基本上,我正在使用Rails2.1编写博客应用程序。我一直在尝试自己完成大部分工作(因为我对Rails有所了解),但在需要时会引用Internet上的教程和引用资料。我设法让一个简单的博客正常运行,然后我尝试添加评论。靠我自己,我设法让它进入了可以从script/console添加评论的阶段,但我无法让表单正常工作。我遵循的其中一个教程建议在帖子Controller中创建一个“评论”操作,以添加评论。我的问题是:这是“标准”方式吗?我的另一个问题的答案之一似乎暗示应该有一个CommentsController参

  7. ruby - Sinatra set cache_control to static files in public folder编译错误 - 2

    我不知道为什么,但是当我设置这个设置时它无法编译设置:static_cache_control,[:public,:max_age=>300]这是我得到的syntaxerror,unexpectedtASSOC,expecting']'(SyntaxError)set:static_cache_control,[:public,:max_age=>300]^我只想将“过期”header设置为css、javaascript和图像文件。谢谢。 最佳答案 我猜您使用的是Ruby1.8.7。Sinatra文档中显示的语法似乎是在Ruby1.

  8. Python 相当于 Perl/Ruby ||= - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。

  9. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  10. Ruby - 如何将消息长度表示为 2 个二进制字节 - 2

    我正在使用Ruby,我正在与一个网络端点通信,该端点在发送消息本身之前需要格式化“header”。header中的第一个字段必须是消息长度,它被定义为网络字节顺序中的2二进制字节消息长度。比如我的消息长度是1024。如何将1024表示为二进制双字节? 最佳答案 Ruby(以及Perl和Python等)中字节整理的标准工具是pack和unpack。ruby的packisinArray.您的长度应该是两个字节长,并且按网络字节顺序排列,这听起来像是n格式说明符的工作:n|Integer|16-bitunsigned,network(bi

随机推荐