2017-05-04 80 views
0

通過這個question是不是,python運行時模型,字典的字典?

globals()去後給全局命名空間(__main__模塊)的字典視圖。

>>> globals() 
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, '__package__': None} 
>>> 

任何新符號(名稱),說operator加入到這個命名空間,將成爲全球命名空間中的一員。

>>> import operator 
>>> globals() 
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, 'operator': <module 'operator' (built-in)>, '__package__': None} 
>>> globals()['operator'] 
<module 'operator' (built-in)> 
>>> 

其中operator是一種新類型str鍵,值是module類型對象。

進一步使用operator模塊(比如__abs__),在當前的命名空間,

>>> globals()['operator']['__abs__'] 

Traceback (most recent call last): 
    File "<pyshell#11>", line 1, in <module> 
    globals()['operator']['__abs__'] 
TypeError: 'module' object has no attribute '__getitem__' 
>>> 

它說,operator模塊不是字典,因爲那裏是名__getitem__沒有屬性。

但是,從我的應用程序(在運行時)的所有代碼,將由globals()函數顯示的字典的一部分。

問:

忽略編碼標準, 在JavaScript中,我可以使用的字典方式來寫我的完整代碼,例如,

> window['Array'] 

      function Array() { [native code] } 


> window['Array']['length'] 
1 

在蟒蛇,爲什麼全局命名空間的成員(鍵)只被視爲字典成員,但不是它們的值(如operator對象)?儘管程序的所有後續代碼都是該字典的一部分。

+1

我不完全相信我理解你的問題。僅僅因爲一個模塊(事實上,大多數對象)可以用'vars(module)'表示爲'dict'並不意味着模塊對象_is_是一個字典,並且應該支持像'dict'這樣的項目訪問。你問你爲什麼'foo.bar'和'foo ['bar']'在python中的含義與它們在Javascript中的含義不同? – mgilson

+0

@mgilson在python中,爲什麼'foo.bar'和'foo ['bar']'意思不一樣?儘管這些全部名字都是'globals()'輸出的字典的一部分。 – overexchange

+0

我認爲更好的問題是爲什麼_他們應該是相同的?當我開始學習JS時,我發現它非常令人吃驚......在python中,'foo.bar'在語義上更加僵化。我期望'foo'是一個帶有'bar'屬性的對象。這給我例如類型信息。 'foo ['bar']'是一個不同的陳述,暗示'foo'是一個容器,通常可以包含_anything_。 – mgilson

回答

2

在Python中,有和subscriptionsattribute references之間的差異,在您使用點訪問屬性的對象語法,在您使用方括號訪問項目對象的

您可以使用特殊方法__getitem__(以及相關的設置方法等)和__getattr__(及相關方法)在您的自定義類型中使用此差異。所以你可以實現你的類型來支持兩種語法來實現相同;或者您可以使用它來爲每種語法指定差異語義,因爲它是標準Python類型的情況。

至於爲什麼做出這種區分,這只是一個語言設計決策,最終使語言更加強大。例如,當字典中還有一個屬性(在這種情況下稱爲dict.update)時,這允許字典具有密鑰'update'

此外,不取決於foo.barfoo['bar']的等同性,避免將訂閱密鑰限制爲字符串,就像JavaScript一樣。相反,我們可以使用任何可哈希對象作爲關鍵。這使dict類型與JavaScripts更新Map type類似,該類型還支持各種各樣的鍵類型。請注意,由於JavaScript的語法選擇較差,因此存在用於訪問地圖項目的explit方法getset

1

1. JS沒有詞典。它們通過使用對象來模擬。 定義一個字典或關聯數組時,你正在做什麼,或者你想用javascript調用它,是 將值賦給一個新對象的屬性。

2. Python具有實際的數據類型字典,即dict(),它是一個對象(Python中的所有內容)專門用於存儲對key:value併爲快速訪問進行了優化。 這實際上是一個容納Python範圍的容器。即當你調用

globals() 

你沒有得到一個全局變量視圖。你確實得到了一個指向真正的全球範圍的指針。 所以,如果你說:

globals()["abcdefgh"] = 123456 

,你將能夠

print abcdefgh 

因爲你直接插入變量ABCDEFGH到口譯全局命名空間持有者。 當您自動使用=賦值運算符時會發生這種情況。

因此,globals()字典包含真實值,它們是對象,但不一定是字典。

在JS你描述的作品,因爲你實際上做的是在Python這樣的:

class obj: pass 

somevar = obj() 
somevar.one = 1 
somevar.two = "two" 
somevar.something = "nothing" 

如果你想看到他們的字典,那麼你必須得給somevar實例的命名空間字典:

print somevar.__dict__ 
somevar.__dict__["blah"] = "xxx" 
print somevar.__dict__ 
print dir(somevar) # To see all attributes of obj() 

否則,它是:

print somevar 
<__main__.obj instance at 0xxxxxxxxx> 

如果你想要的obj()實例充當dict(),那麼你必須爲它實現字典的接口。

在JS中它總是隻是另一個對象,所以語法繼續工作,不管它是如何定義的。