I come from a Javascript background (where properties can be accessed through both . and [] notation), so please forgive me, but what, exactly, is
The dot operator is used for accessing attributes of any object. For example, a complex number
>>> c = 3+4j
has (among others) the two attributes real and imag:
>>> c.real
3.0
>>> c.imag
4.0
As well as those, it has a method, conjugate(), which is also an attribute:
>>> c.conjugate
>>> c.conjugate()
(3-4j)
Square bracket notation is used for accessing members of a collection, whether that's by key in the case of a dictionary or other mapping:
>>> d = {'a': 1, 'b': 2}
>>> d['a']
1
... or by index in the case of a sequence like a list or string:
>>> s = ['x', 'y', 'z']
>>> s[2]
'z'
>>> t = 'Kapow!'
>>> t[3]
'o'
These collections also, separately, have attributes:
>>> d.pop
>>> s.reverse
>>> t.lower
... and again, in the above cases, these attributes happen to be methods.
While all objects have some attributes, not all objects have members. For example, if we try to use square bracket notation to access a member of our complex number c:
>>> c[0]
Traceback (most recent call last):
File "", line 1, in
TypeError: 'complex' object is not subscriptable
... we get an error (which makes sense, since there's no obvious way for a complex number to have members).
It's possible to define how [] and . access work in a user-defined class, using the special methods __getitem__() and __getattr__() respectively. Explaining how to do so is beyond the scope of this question, but you can read more about it in the Python Tutorial.