完成此question
之后 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
在python中,为什么全局命名空间成员(键)只被视为字典成员而不是它们的值(如operator
对象)?尽管您的程序的所有后续代码都是该字典的一部分。
答案 0 :(得分:2)
在Python中,attribute references(使用点来访问对象的属性的语法)和使用方括号访问的subscriptions之间存在差异对象的项。
您可以使用特殊方法__getitem__
(以及相关的设置方法等)和__getattr__
(以及相关方法)在自定义类型中使用此差异。所以你可以实现你的类型以支持两种语法来实现相同的功能;或者您可以使用它为每种语法分配差异语义,就像标准Python类型一样。
至于为什么要进行这种区分,这只是一种语言设计决策,最终使语言更加强大。例如,这允许字典具有键'update'
,此时还有一个属性 - 在这种情况下是一种方法 - 称为dict.update
。
此外,不依赖于foo.bar
和foo['bar']
的等效性,可以避免将订阅键限制为字符串,就像JavaScript的情况一样。相反,我们可以使用任何可散列对象作为键。这使dict
类型类似于JavaScripts更新Map
type,它也支持各种键类型。请注意,由于JavaScript的语法选择较差,因此可以使用explit方法get
和set
来访问地图项。
答案 1 :(得分:1)
1。 JS没有字典。它们通过使用对象进行模拟。 在定义字典或关联数组时你正在做什么,或者你想在javascript中调用它 将值赋给新对象的属性。
2。 Python有实际的数据类型字典,即dict(),它是一个对象(Python中的所有东西)专门用于存储对键:值并针对快速访问进行了优化。 这实际上是一个容纳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"
如果你想将它们视为dict,那么你必须得到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中,它始终只是另一个对象,因此无论首先如何定义语法,语法都会继续有效。