Какая разница между квадратными скобками и точками в 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
.