【问题标题】:Is not, python runtime model, dictionaries of dictionaries?是不是,python运行时模型,字典中的字典?
【发布时间】:2017-05-04 22:21:17
【问题描述】:

经过这个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对象)?尽管您程序的所有后续代码,都是该字典的一部分。

【问题讨论】:

  • 我不完全确定我是否理解您的问题。仅仅因为一个模块(实际上是大多数对象)可以使用vars(module) 表示为dict 并不意味着模块对象 一个字典并且应该支持像@987654340 这样的项目访问@。你在问为什么foo.barfoo['bar'] 在 Python 中的含义与在 Javascript 中的含义不同?
  • @mgilson 在python中,为什么foo.barfoo['bar']的意思不一样?尽管所有这些名称都是 globals() 输出的字典的一部分。
  • 在 Javascript 中,对象和字典是一回事,你可以使用.[] 语法,具体取决于属性是文字还是动态。 Python 有不同的对象和字典(字典是特定类型的对象),属性不同于字典元素。
  • globals() 返回一个字典这一事实并不意味着 Python 字典实际上就是所有这些的实现方式。
  • @juanpa.arrivillaga -- 但它大部分是如何实现的。最值得注意的例外是具有__slots__locals() 的类。关键区别在于foo.bar 通常在foo.__dict__ 中查找bar 键。这允许很多非常酷的东西。例如你可以拥有@property,它在查找时调用一个函数。您可以拥有一个对象,其中foo.getfoo['get']不同的 事物。它还鼓励结构。 foo.barfoo['bar'] 已经发展为具有非常清晰且不同的语义。

标签: javascript python dictionary


【解决方案1】:

在 Python 中,attribute referencessubscriptions 之间存在区别,attribute references 使用点访问对象的属性,而subscriptions 使用方括号访问项目 一个对象。

您可以通过使用特殊方法__getitem__(以及设置等相关方法)和__getattr__(以及相关方法)在自定义类型中使用这种差异。所以你可以实现你的类型来支持这两种语法来达到同样的效果;或者您可以使用它为每种语法分配不同的语义,就像标准 Python 类型的情况一样。

至于为什么要做出这种区分,这只是一个语言设计决策,最终使语言变得更强大。例如,这允许字典有一个键 'update',而此时还有一个属性——在本例中是一个方法——称为 dict.update

此外,不依赖于 foo.barfoo['bar'] 的等价性避免了将订阅键限制为字符串,就像 JavaScript 的情况一样。相反,我们可以使用任何可散列的对象作为键。这使得类似于 JavaScript 的 dict 类型更新为 Map type,它也支持广泛的键类型。请注意,由于 JavaScript 的语法选择较差,因此有 explit 方法 getset 来访问地图项。

【讨论】:

    【解决方案2】:

    1。 JS 没有字典。它们是通过使用对象来模拟的。 在定义字典或关联数组时,您正在做什么,或者您想在 javascript 中调用它是 为新对象的属性赋值。

    2。 Python 有实际的数据类型字典,即 dict(),它是一个对象(Python 中的一切都是)专门用于存储对 key: value 并针对快速访问进行了优化。 这实际上是一个包含 Python 作用域的容器。 IE。当你打电话时

    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 中,它始终只是另一个对象,因此无论最初是如何定义的,语法都会继续工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-28
      • 2017-09-08
      • 2020-09-08
      • 2012-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多