7

我一直在同时学习 Ruby 和 Python,我注意到的一件事是这两种语言似乎以不同的方式对待范围。这是我的意思的一个例子:

# Python
a = 5
def myfunc():
  print a

myfunc() # => Successfully prints 5

# Ruby
a = 5
def myfunc
  puts a
end

myfunc # => Throws a "NameError: undefined local variable or method `a' for main:Object"

似乎 def 块可以访问在 Python 中其直接范围之外声明的变量,但在 Ruby 中则不能。有人可以确认我的理解是否正确吗?如果是这样,这些思考范围的方式中的一种是否在编程中更常见?

4

3 回答 3

5

免责声明:我不是 python 专家

在 python 中,模块中定义的变量默认是模块变量,因此是该模块的全局变量。在 Ruby 中,当您定义一个小写变量时,它始终是一个局部变量。局部变量只能在定义它们的块中以及在包装变量的块中定义的 procs/lambdas 中访问。

在 Ruby 中,对于跨范围的变量,它需要是:

  • 常量 ( ALL_CAPS):总是可访问的,如果以正确的范围为前缀
  • 类变量 ( @@double_at):始终可以从定义类和任何子类访问,但不能从外部访问
  • 实例变量 ( @single_at):只能从该对象内部访问,并且可以从外部使用 getter 方法/ 访问get_instance_variable
  • 全局 ( $starts_with_dollar):一个坏主意。跨越所有范围,不需要范围。不使用!
于 2013-02-23T16:47:18.377 回答
1

在 Ruby 中,如果您想访问在您正在调用的方法之外定义的变量,您需要将其定义为全局变量。Ruby 尝试匹配本地范围内定义的变量,如果没有找到,则抛出异常。

你可以定义一个带$符号的全局变量。

$a = 5
def myfunc
  puts $a
end

myfunc

然而,作为一般规则,定义全局变量并不是一个好习惯,否则会冒着污染全局命名空间的风险。

于 2013-02-23T16:35:30.027 回答
1

您可以使用dis模块来查看 Python 正在做什么。

import dis

a = 5
def myfunc():
  print a

结果:

>>> dis.dis(myfunc)
 15           0 LOAD_GLOBAL              0 (a)
              3 PRINT_ITEM          
              4 PRINT_NEWLINE       
              5 LOAD_CONST               0 (None)
              8 RETURN_VALUE

所以你可以看到它a在全局范围内。

于 2013-02-23T18:20:35.673 回答