0

After going through this question

globals() give the dictionary view of the global namespace(__main__ module).

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

Any new symbol(name), say operator added to this namespace, will become a member of that global name space.

>>> 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)>
>>> 

where operator is a new str type key, value is the module type object.

further on using operator module(say __abs__), in current namespace,

>>> 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__'
>>> 

It says, operator module is not a dictionary because there is no attribute by name __getitem__.

But, all the code from my application(in runtime), will be part of the dictionary shown by globals() function.

Question:

Ignoring coding standards, In JavaScript, I can use dictionary notation to write my complete code, for example,

> window['Array']

            function Array() { [native code] }


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

In python, Why global namespace members(keys) are only viewed as dictionary members but not their values(like operator object)? Despite all the subsequent code of your program, is part of that dictionary.

Community
  • 1
  • 1
overexchange
  • 15,768
  • 30
  • 152
  • 347
  • 1
    I'm not completely sure that I'm understanding your question. Just because a module (and indeed, most objects) can be represented as a `dict` using `vars(module)` doesn't mean that the module object _is_ a dict and should support item access like a `dict`. Are you asking why `foo.bar` and `foo['bar']` don't mean the same thing in Python as they do in Javascript? – mgilson May 04 '17 at 22:26
  • @mgilson In python, why `foo.bar` and `foo['bar']` don't mean the same? despite these all name are part of dictionary that `globals()` output. – overexchange May 04 '17 at 22:31
  • I think a better question is why _should_ they be the same? I found it very surprising when I started learning JS that they are ... In python, `foo.bar` is semantically a more rigid statement. I expect `foo` to be an object with a `bar` attribute. This gives me type information for example. `foo['bar']` is a different statement which implies that `foo` is a container and can often contain just about _anything_. – mgilson May 04 '17 at 22:34
  • 1
    In Javascript, objects and dictionaries are the same thing, and you can use `.` or `[]` syntax depending on whether the property is literal or dynamic. Python has distinct object and dictionaries (a dictionary is a specific type of object), and properties are different from dictionary elements. – Barmar May 04 '17 at 22:40
  • @Barmar How do you understand [this](http://stackoverflow.com/a/22605333/3317808)? – overexchange May 04 '17 at 22:44
  • 1
    The fact that `globals()` **returns a dict** does not mean that Python dictionaries are actually how all of this is implemented. – juanpa.arrivillaga May 04 '17 at 22:51
  • 1
    @juanpa.arrivillaga -- But it _is_ how most of it is implemented. The most notable exceptions are classes with `__slots__` and `locals()`. The key distinction is that `foo.bar` usually looks up a `bar` key inside `foo.__dict__`. this allows for a lot of really cool things. e.g. you can have `@property` which calls a function on lookup. You can have an object where `foo.get` and `foo['get']` are _different_ things. It also encourages structure. `foo.bar` and `foo['bar']` have evolved to have _very_ clear and different semantics. – mgilson May 04 '17 at 23:06
  • @juanpa.arrivillaga No, interpreter really stores variables in them. – Dalen May 04 '17 at 23:35

2 Answers2

2

In Python, there is a difference between attribute references, the syntax where you use dots to access attributes of objects, and subscriptions, where you use square brackets to access items of an object.

You can use this difference in your custom types by using the special methods __getitem__ (and the related methods for setting etc.) and __getattr__ (and related methods). So you can implement your types to support both syntaxes to achieve the same; or you can use it to assign difference semantics to each syntax as it is the case for standard Python types.

As for why this distinction is made, this is simply a language design decision that was made, which ultimately makes the language more powerful. For example, this allows a dictionary to have a key 'update', when there is also an attribute—a method in this case—called dict.update.

Also, not depending on the equivalence of foo.bar and foo['bar'] avoids limiting subscription keys to strings, like it is the case with JavaScript. Instead, we can use any hashable object as a key. This makes the dict type similar to JavaScripts newer Map type which also supports a wide range of key types. Note that because of JavaScript’s inferior syntax choices, there are explit methods get and set to access the map items.

poke
  • 369,085
  • 72
  • 557
  • 602
1

1. JS doesn't have dictionaries. They are emulated by using objects. What you are doing when defining a dictionary or associative array, or however you want to call it in javascript is assigning values to attributes of a new object.

2. Python has actual data type dictionary i.e. dict() which IS AN OBJECT (everything in Python is) specialized to store pairs key: value and optimized for fast access. This is actually a container that holds Python scopes. I.e. when you call

globals()

You do not get a view of global variables. You do get a pointer to the real global scope. So, if you say:

globals()["abcdefgh"] = 123456

you will be able to

print abcdefgh

because you directly inserted the variable abcdefgh into interpreters global namespace holder. This happens when you use = assignment operator automatically.

So, globals() dictionary contains real values, which are objects, but not necessarily dictionaries.

In JS what you describe works, because what you are actually doing is in Python this:

class obj: pass

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

And if you want to see them as dict, then you have to get to the somevar instance's namespace dictionary:

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

Otherwise it is:

print somevar
<__main__.obj instance at 0xxxxxxxxx>

And if you want the obj() instance to act as a dict() then you have to implement the dictionary's interface for it.

In JS it is always just another object, so syntax continues to work regardless on how it was defined in the first place.

Dalen
  • 4,128
  • 1
  • 17
  • 35