2013-02-23 91 views
5

我一直在同时学习Ruby和Python,并且我注意到的一件事是这两种语言似乎以不同的方式处理作用域。下面是我的意思的例子: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中声明的变量。有人可以确认我的理解是否正确?如果是这样,这些思维范围的方式在编程中是否更常见?

+0

对于Python方面,你是对的(显然更多的是范围界定,但你的措辞并不矛盾任何它)。 – delnan 2013-02-23 16:24:58

+0

可能的Python答案在这里:http://stackoverflow.com/questions/370357/python-variable-scope-question – 2013-02-23 16:27:36

回答

4

免责声明:我不是蟒蛇专家

在Python中,其中一个模块中定义的变量是,默认情况下,模块变量,因此全球该模块。在Ruby中,当你定义一个小写变量时,它总是一个局部变量。局部变量只能在定义它们的块中以及在包含该变量的块中定义的procs/lambdas中访问。

在Ruby中,用于可变交叉范围,它需要是以下之一:

  • 恒定(ALL_CAPS):总是可访问的,如果前缀与右范围
  • 类变量(@@double_at):始终可以从定义的类和任何子类访问,但不能从外部访问
  • 实例变量(@single_at):仅可从该对象内部和外部使用getter方法/ get_instance_variable访问。
  • Global($starts_with_dollar):一个坏主意。跨越所有范围,不需要确定范围。不使用!
+0

啊我看,所以对于Python来说,当你在任何类或块之外定义一个变量时,默认情况下它将在全局范围内。这与Ruby相反,Ruby将每个范围视为自己的独立实体,并且通过使用$定义全部范围内可访问的全局变量。这是一个精确的总结吗? – wmock 2013-02-23 17:30:15

+0

@WillsonMock:非常漂亮。 – Linuxios 2013-02-23 19:04:49

+2

Minor nitpick:常量不是ALL_CAPS,它们只是以大写字母开头。例如类名是常量。 – steenslag 2013-02-23 20:34:32

1

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

您可以使用$符号定义全局变量。

$a = 5 
def myfunc 
    puts $a 
end 

myfunc 

但是,作为一般规则,定义全局变量不是一种好的做法,否则将会有污染全局名称空间的风险。

+3

这显然是错误的。一个实例变量('@ a')就足够了。 – steenslag 2013-02-23 20:30:21

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是在全球范围内。