【问题标题】:What happens if you write a variable name alone in python?如果你在python中单独写一个变量名会发生什么?
【发布时间】:2014-02-11 04:50:07
【问题描述】:

最近我开始好奇,但以下虚假 python 代码的第 2 行发生了什么:

def my_fun(foo,bar):
    foo
    return foo + bar

我开始感兴趣的原因是我正在尝试 Light Table 并尝试在“foo”上放置手表。它似乎导致 python 解释器挂起。

我认为这条线完全没有效果并且不会引起任何错误,我是否正确?有人能解释一下解释器到底做了什么吗?

【问题讨论】:

    标签: python lighttable


    【解决方案1】:

    借助内置的dis 模块,您可以查看正在发生的事情:

    import dis
    
    def my_fun(foo,bar):
        foo
        return foo + bar
    
    dis.dis(my_fun)
    

    dis.dis 函数反汇编函数(是的,它可以反汇编自身)、方法和类。

    dis.dis(my_fun) 的输出为:

      4           0 LOAD_FAST                0 (foo)
                  3 POP_TOP
    
      5           4 LOAD_FAST                0 (foo)
                  7 LOAD_FAST                1 (bar)
                 10 BINARY_ADD
                 11 RETURN_VALUE
    

    前两个字节码正是我们需要的:foo 行。

    这些字节码的作用如下:

    1. 第一个将对局部变量foo的引用压入堆栈 (LOAD_FAST)
    2. 第二个删除栈顶 (POP_TOP)

    基本上,foo 行没有任何作用。 (好吧,如果没有定义foo 变量,那么LOAD_FAST 将抛出NameError

    【讨论】:

      【解决方案2】:

      什么都没有发生。它变得等同于无意义的操作 查看dis 输出

      In [3]: dis.dis(my_fun)
        2           0 LOAD_FAST                0 (foo)
                    3 POP_TOP             
      
        3           4 LOAD_FAST                0 (foo)
                    7 LOAD_FAST                1 (bar)
                   10 BINARY_ADD          
                   11 RETURN_VALUE 
      

      我们可以看到它对foo 的加载速度很快,然后什么也不做。

      【讨论】:

      • + 1,我不知道dis
      【解决方案3】:

      在命令行尝试一下:它只返回foo 中的值。 这并不意味着它在某些特殊情况下不会产生副作用:如果您执行以下操作:

      def my_fun(foo, bar):
          foo.prop
          return foo.func(bar)
      

      尽管从技术上讲我们刚刚返回了值,但如果它被定义为属性,那么foo.prop 实际上可以调用一个函数。

      但通常...您不会在模块中执行此操作,只能在交互式控制台中执行此操作。

      【讨论】:

        【解决方案4】:

        foo 语句是expression statement 的一个示例,因此当解释器遇到它时会对其进行评估。

        表达式语句计算表达式列表(可能是 单个表达式)。

        所以foo 被加载,表达式被求值(它本身就是foo,所以不需要进一步的操作),结果立即被遗忘。

        【讨论】:

          【解决方案5】:

          什么都没有发生:

          >>> def baz(foo, bar):
              foo
              return bar
          
          >>> baz(10, 20)
          20
          

          声明无效。

          【讨论】:

          • 虽然你的结论是正确的,但你的论点是假的。仅仅因为它在您发现的一种情况下什么都不做,并不意味着它在所有情况下都不做。
          猜你喜欢
          • 1970-01-01
          • 2016-12-12
          • 1970-01-01
          • 2011-09-17
          • 2019-01-09
          • 1970-01-01
          • 2011-07-06
          • 2017-02-04
          • 1970-01-01
          相关资源
          最近更新 更多