2013-02-23 47 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是在全球範圍內。