Как Python различает разные типы данных? - PullRequest
6 голосов
/ 15 марта 2010

Извините, если это для вас довольно нудистно, но я только начинаю изучать Python после изучения C ++ и Java, и мне интересно, как в мире я мог бы просто объявить переменные типа id = 0 и name = 'John' без любые int или string впереди! Я понял, что, возможно, это потому, что в числе нет ', но как бы Python вычислил это в чем-то вроде def increase(first, second) вместо чего-то вроде int increase(int first, int second) в C ++?!

Ответы [ 5 ]

13 голосов
/ 15 марта 2010

Буквальные объекты, которые вы упоминаете, несут (указатели на ;-) свои собственные типы с ними, конечно, поэтому, когда имя связано с этим объектом, проблема типа не возникает - у объекта всегда есть тип, имя не - просто делегирует это объекту, с которым он связан.

Нет никакого "выяснения" в def increase(first, second): - имя increase привязывается к объекту функции, имена first и second записываются как параметры-имена и будут привязаны (вполне возможно, к объектам разные типы в разных точках) как increase вызывается.

Так, скажем, тело - return first + second - тогда вызов increase('foo', 'bar') с радостью вернет 'foobar' (делегируя добавление к объектам, которые в данном случае являются строками), и, возможно, позже вызов increase(23, 45) с таким же успехом вернет 68 - снова, делегировав дополнение к объектам, связанным с теми именами в точке вызова, которые в данном случае являются целыми числами. И если вы вызываете с несовместимыми типами, вы получите исключение, так как делегированная операция сложения не может понять ситуацию - ничего страшного!

7 голосов
/ 15 марта 2010

Python динамически типизирован : все переменные могут ссылаться на объект любого типа. id и name могут быть чем угодно, но фактические объекты имеют типы типа int и str. 0 - это литерал, который анализируется для создания объекта int, а 'John' - литерал, который создает объект str. Многие типы объектов не имеют литералов и возвращаются вызываемым объектом (например, frozenset - нет способа создать литерал frozenset, вы должны вызвать frozenset.)

Следовательно, не существует такого понятия, как объявление переменных, поскольку вы ничего не определяете относительно переменной. id = 0 и name = 'John' являются просто назначением.

increase возвращает int, потому что это то, что вы возвращаете в нем; ничто в Python не заставляет его быть другим объектом. first и second - только целые числа, если вы их сделаете.

Объекты, в определенной степени, имеют общий интерфейс. Вы можете использовать одни и те же операторы и функции на всех них, и если они поддерживают эту конкретную операцию, это работает. Это распространенный, рекомендуемый метод использования различных типов, которые ведут себя одинаково взаимозаменяемо; это называется утка, набрав . Например, если что-то принимает объект file, вы можете вместо этого передать объект cStringIO.StringIO, который поддерживает тот же метод, что и файл (например, read и write), но это совершенно другой тип. Это похоже на интерфейсы Java, но не требует формального использования, вы просто определяете соответствующие методы.

6 голосов
/ 15 марта 2010

Python использует метод типизации утки - если он ходит, выглядит и крякает как утка, то это утка. Если вы передадите строку и попытаетесь с ней что-то сделать числовой, то она потерпит неудачу.

Посмотрите: http://en.wikipedia.org/wiki/Python_%28programming_language%29#Typing и http://en.wikipedia.org/wiki/Duck_typing

4 голосов
/ 15 марта 2010

Когда речь идет о присвоении литеральных значений переменным, тип литерального значения может быть выведен во время лексического анализа. Например, все, что соответствует регулярному выражению (-)?[1-9][0-9]*, может быть выведено как целочисленный литерал. Если вы хотите преобразовать его в число с плавающей точкой, необходимо явное приведение. Аналогично, строковый литерал - это любая последовательность символов, заключенная в одинарные или двойные кавычки.

При вызове метода параметры не проверяются типом. Вам нужно только ввести правильное количество из них, чтобы иметь возможность вызывать метод. До тех пор, пока тело метода не вызывает ошибок в отношении аргументов, вы можете вызывать один и тот же метод с множеством различных типов аргументов.

0 голосов
/ 15 марта 2010

В Python, в отличие от C ++ и Java, числа и строки являются объектами. Итак, это:

   id = 0
   name = 'John'

эквивалентно:

   id = int(0)
   name = str('John')

Поскольку переменные id и name являются ссылками, которые могут обращаться к любому объекту Python, их не нужно объявлять определенным типом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...