Python возвращает пользовательские объекты

avatar
biskit1967
7 апреля 2018 в 22:49
2178
2
-1

Программист .NET с большим стажем, новичок в изучении Python.

В .NET, если вы хотите получить запись о клиенте из базы данных и сделать что-то с информацией в пользовательском интерфейсе, вы можете сделать это следующим образом

Customer customer = ReadCustomerRecord (12345)

Клиент — это настраиваемый объект, содержащий пару десятков полей о покупателе. ReadCustomerRecord подключается к базе данных, считывает запись и заполняет поля в объекте Customer, а затем возвращает ее.

Теперь я не понимаю, как вы делаете то же самое в Python. Если я просто возвращаю объект клиента из метода, выполняющего инициализацию, как сообщить коду, какой это тип объекта?

Источник
Gomes J. A.
7 апреля 2018 в 22:52
2

Не могли бы вы предоставить фрагмент кода, описывающий вашу проблему?

Sumner Evans
7 апреля 2018 в 22:53
6

Вам не нужно указывать Python, какой это тип объекта. В Python информация о типе хранится в данных, а не в переменной.

juanpa.arrivillaga
7 апреля 2018 в 22:54
0

Что именно вы спрашиваете. Вы спрашиваете, как писать пользовательские классы на Python? Потому что вы специально спрашиваете: «Как мне указать коду, какой это тип объекта?» в этом случае ответ заключается в том, что в Python вы этого не сделаете.

rafaelc
7 апреля 2018 в 22:58
1

В python вы можете сделать x = 2 и сразу после x = "hello". Нет статической типизации

Gomes J. A.
7 апреля 2018 в 23:01
0

Теперь, если вы хотите проверить, имеет ли конкретный объект определенный тип, вы можете использовать isisntance(obj, type) для экземпляров и `issubclass(obj.__class__, type) для классов.

Ответы (2)

avatar
abarnert
7 апреля 2018 в 23:29
1

Во-первых, Python имеет необязательную статическую типизацию, если вы этого хотите. Синтаксис немного отличается от C#, но такой же, как и у многих других языков:

.
customer: Customer = ReadCustomerRecord(12345)

Если вы затем запустите свой код через Mypy или другое средство проверки или анализатор статического типа (многие IDE интегрированы, поэтому вам не нужно ничего делать), он сможет проверить, что единственные вещи, которые вы когда-либо хранили, в customer являются значениями типа Customer, и вы никогда не делаете с ними ничего, что недопустимо для значений этого типа.


Однако, даже если вы используете статическую проверку типов, вам не нужно указывать тип каждой переменной, потому что большинство из них можно определить автоматически. Опять же, это отличается от C#, но это то же самое, что и многие другие языки, включая языки со статической типизацией с более строгими правилами и более мощными системами типов, чем C#, такие как Swift, Rust или F#.

"Вывод" означает, что если вы не укажете тип, программа статической проверки определит, что customer должно быть Customer, потому что это то, что возвращает ReadCustomerRecord. И тогда он сможет проверять все то же самое, что и раньше.

Как и в Swift или Go, в Python идиоматично не указывать типы переменных, за исключением случаев, когда это либо показывает что-то неочевидное или иным образом полезно для читателей, либо разрешает что-то неоднозначное для средства статической проверки.

Среди современных языков только языки семейства C (C, C++, Java, C# и т. д.) требуют указывать тип всего по имени, даже если это совершенно очевидно — и даже многие из них дать вам что-то вроде auto, которое можно использовать, чтобы указать компилятору вывести тип.


Но большая разница между Python и другими языками, о которых я упоминал, заключается в том, что Python динамически типизируется. Статическая проверка может проверить ваши типы переменных, но реальный компилятор и интерпретатор не заботятся о них. На самом деле переменные вообще не имеют типов.

В Python это значения, которые имеют типы. Переменные — это просто имена для значений, и совершенно законно (а иногда идиоматично) повторно использовать одно и то же имя для разных значений разных типов в разное время.

Статическая проверка предназначена для того, чтобы доказать, что вы не используете динамические функции, когда вы думаете, что это не так, и она убирается, когда вам нужны эти динамические функции.


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

.

Итак, вы, вероятно, просто хотите написать эту строку как:

customer = ReadCustomerRecord(12345)

Но если читателю непонятно, какой это будет тип, можно сделать так:

customer: Customer = ReadCustomerRecord(12345)

И если вам нужно использовать утиную печать с customer, но статический тип, проверьте все вокруг него:

customer: Any = ReadCustomerRecord(12345)
biskit1967
8 апреля 2018 в 00:37
1

Отлично, именно то, что я спрашивал. Спасибо за понимание вопроса.

rafaelc
8 апреля 2018 в 15:55
0

Обратите внимание, что этот синтаксис специфичен для python3 и что он не приведет к ошибкам, как c#, если есть несоответствия типов; то есть команда x: int = "hello" работает, и x становится str вместо int, даже если вы ясно указали читателю, что это int.

abarnert
8 апреля 2018 в 20:36
0

@RafaelC Я начинаю с того, что говорю: «Если вы затем запустите свой код через MyPy…», а позже посвятите целый раздел «Статическая проверка может проверить ваши типы переменных, но настоящий компилятор и интерпретатор не заботятся о них…»

abarnert
8 апреля 2018 в 20:39
0

@RafaelC Что касается Python3: сейчас 2018 год. До окончания поддержки Python 2.7 осталось менее 2 лет. Я не думаю, что необходимо больше усложнять каждый ответ, объясняя Python 2, если только нет оснований полагать, что OP использует Python 2. Особенно в этом случае, когда потребуется описать либо синтаксис комментариев, либо набранные файлы и инструменты вы можете использовать для преобразования в аннотации при последующем обновлении, что все намного усложняет.

avatar
138
7 апреля 2018 в 22:53
1

Изучите классы Python.

Пример

class Customer:
    #constructor, self == this
    def __init__(self, data):
         self.data = data

def ReadCustomerRecord (cust_id):
    ## get from db
    cust = Customer(data)
    return cust

customer = ReadCustomerRecord(1234)

Python — это язык с динамической типизацией, что означает, что проверка типов выполняется во время выполнения программы. Все типы являются неявными, фактически методы могут возвращать различные типы в зависимости от условия.

def func(is_list):
    if is_list:
        return [1,2,3]
    else:
        return 1
juanpa.arrivillaga
7 апреля 2018 в 22:59
2

Ваша точка зрения по-прежнему заключается в том, что типы являются неявными, но это: «значение, что объекты могут быть преобразованы в различные типы без явного приведения» определенно неверно.

138
7 апреля 2018 в 23:01
0

Вы правы, я сделал небольшую поправку, чтобы уточнить

juanpa.arrivillaga
7 апреля 2018 в 23:04
2

«является динамически типизированным языком, означающим, что объекты имеют один базовый тип с именем object, что позволяет нескольким производным типам быть возвращаемым типом функции». все равно не правильно. Все, что означает динамическая типизация, это то, что проверка типов выполняется во время выполнения. Python variables не типизированы, поэтому переменные могут ссылаться на объекты любого типа. Обратите внимание, что многие статически языки ООП получают все объекты из одного типа, так что это не имеет большого значения.

138
7 апреля 2018 в 23:09
0

исправлено, спасибо за разъяснения, я неправильно использовал динамическую типизацию и слабую типизацию