Какая разница между квадратными скобками и точками в Python?

Я исхожу из фона Javascript (где свойства можно получить через обозначения . и []), поэтому, пожалуйста, простите меня, но в чем разница между ними в Python?

Из моих экспериментов видно, что [] всегда следует использовать, чтобы получить индекс list или set и получить значение от определенного ключа в dictionary. Правильно ли это, а если нет, когда вы используете . в Python?

Ответ 1

Точечный оператор используется для доступа к атрибутам любого объекта. Например, комплексное число

>>> c = 3+4j

имеет (среди прочих) два атрибута real и imag:

>>> c.real
3.0
>>> c.imag
4.0

Кроме того, он имеет метод conjugate(), который также является атрибутом:

>>> c.conjugate
<built-in method conjugate of complex object at 0x7f4422d73050>
>>> c.conjugate()
(3-4j)

Обозначение квадратной скобки используется для доступа к членам коллекции, будь то ключом в случае словаря или другого отображения:

>>> d = {'a': 1, 'b': 2}
>>> d['a']
1

... или индексом в случае последовательности, такой как список или строка:

>>> s = ['x', 'y', 'z']
>>> s[2]
'z'
>>> t = 'Kapow!'
>>> t[3]
'o'

Эти коллекции также, отдельно, имеют атрибуты:

>>> d.pop
<built-in method pop of dict object at 0x7f44204068c8>
>>> s.reverse
<built-in method reverse of list object at 0x7f4420454d08>
>>> t.lower
<built-in method lower of str object at 0x7f4422ce2688>

... и снова, в приведенных выше случаях, эти атрибуты являются методами.

Пока все объекты имеют некоторые атрибуты, не все объекты имеют члены. Например, если мы попытаемся использовать квадратную скобку для доступа к члену нашего комплексного номера c:

>>> c[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'complex' object is not subscriptable

... мы получаем ошибку (что имеет смысл, так как нет очевидного способа, чтобы комплексное число имело членов).

Можно определить, как работать [] и . в пользовательском классе, используя специальные методы __getitem__() и __getattr__() соответственно. Объяснение, как это сделать, выходит за рамки этого вопроса, но вы можете прочитать больше об этом в Python Tutorial.

Ответ 2

. используется для доступа к атрибутам (включая методы). [] используется для доступа к тем, которые называются "элементами", которые обычно представляют собой содержимое различных видов контейнерных объектов.

JavaScript не различает эти две вещи, но Python делает. Вы правы, что [] используется для доступа к данным в списке или dict. . используется, например, для доступа к таким методам, как list.append и dict.update. Он также используется для доступа к другим данным по другим видам объектов; например, скомпилированные объекты регулярного выражения имеют атрибут pattern, содержащий шаблон регулярного выражения (вы получите доступ к нему с помощью rx.pattern).

В общем, соглашение состоит в том, что [] используется для хранения данных с открытым контентом, где вы заранее не знаете, сколько или каких видов данных будет храниться объект; . чаще используется для конкретных данных, которые объект имеет "по своей природе" и к которому обращается с предопределенным именем. Например, просто зная, что что-то в списке не говорит вам, что в нем (для которого вы используете []), но он говорит вам, что вы можете добавить к нему (и получить доступ к методу добавления, который вы используете .).

Другим существенным различием между Python и JavaScript в этом отношении является то, что в Python поведение как ., так и [] может быть изменено объектом. Поэтому obj.foo или obj[foo] может делать что-то особенное, если obj - это объект, который определяет для себя собственное поведение. Существуют различные пользовательские типы, которые используют это для своих целей.

Ответ 3

[] - это индекс для контейнера, такой как список или словарь.

. является членом объекта и модулей. Это может быть метод, данные участника или атрибут.

>>> xs = [1, 7, 3, 4, 5, 4, 3, 4, 1]

>>> xs.count(4)
3

>>> xs[1]
7

Ответ 4

На самом деле, Python использует квадратные скобки, чтобы заключить ключ. Для списков это целочисленный (беззнаковый) индекс или срез, тогда как для dicts это (допустимый) объект, такой как строка, кортеж и т.д. Или даже целое число (singe и unsigned). Это прямо на многих других языках, которые используют одинаковый или даже идентичный синтаксис.

. используется для доступа к элементам объекта, как и для С++, C, Java, JavaScript и т.д. Было бы довольно просто написать класс словаря, который позволяет использовать dot-синтаксис для доступа к его элементы. Однако для этого ключи должны быть действительными идентификаторами Python (letter { letter | digit | _ }. Однако это не очень распространено.

Набор не поддерживает индексирование, поскольку он не упорядочен внутренне и не существует отношения между "ключом" и "значением". Для списка вы не "получаете индекс", но вы "получаете значение для индекса". Для dict это похоже, но "индекс" более гибкий. Тем не менее, dict не разрешает нарезку и (как набор) неупорядочен.

Sidenote: Python использует внутренний dict для объекта для организации своих членов. Просто попробуйте на консоли:

class MyClass:
    def myfunc(self):
        pass

print(MyClass.__dict__)

Вы получите весь атрибут (имя: значение) этого класса. Обратите внимание на запись для myfunc.