Уведомления

Группа в Telegram: @pythonsu

#1 Май 11, 2019 14:51:30

lerr
Зарегистрирован: 2018-07-22
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Подскажите по преобразованию типов в классах

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

 class C():
    ....
    def __add__(self, other):
        return type(self)(self.val + other.val)
    ....

type(self) когда нужно такое преобразование типа и нужно ли вообще ?

Офлайн

#2 Май 11, 2019 14:57:31

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Подскажите по преобразованию типов в классах

lerr
в питоне не нужно никогда, в других языках бывает по-разному.



Офлайн

#3 Май 11, 2019 15:53:47

lerr
Зарегистрирован: 2018-07-22
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Подскажите по преобразованию типов в классах

FishHook
тут может использоваться приоритет на использовании метода __str__(self), если он например вообще не определен в родительском классе. Другого применения даже не представляю. (возможно ошибаюсь)

Офлайн

#4 Май 11, 2019 16:22:08

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Подскажите по преобразованию типов в классах

lerr
вы вообще не понимаете, что делает type в питоне, поэтому, да, не представляете



Офлайн

#5 Май 11, 2019 16:27:24

Egorro13
Зарегистрирован: 2019-04-16
Сообщения: 105
Репутация: +  5  -
Профиль  

Подскажите по преобразованию типов в классах

type(self)

lerr
тут может использоваться приоритет на использовании метода __str__(self), если он например вообще не определен в родительском классе. Другого применения даже не представляю. (возможно ошибаюсь)
type(self) - конструктор объекта текущего класса, (self.val + other.val) - параметр конструктора, т.е. сумма складываемых значений. Тоже стало интересно, в чем смысл такого приведения - попробовал набросать возможный вариант:
 class C:
    def __init__(self, v) -> None:
        self.val = v
    def __add__(self, other):
        return type(self)(self.val + other.val)
    def __str__(self) -> str:
        return f"C: value={self.val}"
class D(C):
    def __str__(self) -> str:
        return f"D: value={self.val}"
c1, c2 = C(1), C(2)
print(c1 + c2)
d1, d2 = D(100), D(150)
print(d1 + d2) # благодаря приведению сумма - объект класса D, а не C

Офлайн

#6 Май 11, 2019 16:39:40

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Подскажите по преобразованию типов в классах

Egorro13
type(self) - конструктор объекта текущего класса
нет, type это не конструктор объектов, а конструктор типов. В питоне типы создаются динамически, а type - базовый метакласс для всех типов.
В вашем примере, класс (то есть тип объекта) и так известен, использовать type бессмысленно.

     def __add__(self, other):
        return С(self.val + other.val)

     def __add__(self, other):
        return self.__class__(self.val + other.val)



Отредактировано FishHook (Май 11, 2019 16:40:12)

Офлайн

#7 Май 11, 2019 16:47:27

Egorro13
Зарегистрирован: 2019-04-16
Сообщения: 105
Репутация: +  5  -
Профиль  

Подскажите по преобразованию типов в классах

FishHook
нет, type это не конструктор объектов, а конструктор типов. В питоне типы создаются динамически, а type - базовый метакласс для всех типов.
Так речь же о type(self), а не просто type - судя по всему, возвращается что-то типа ссылки на класс объекта self, эту ссылку дальше используем для вызова конструктора, т.е. создания объекта?
FishHook
В вашем примере, класс (то есть тип объекта) и так известен, использовать type бессмысленно.
Добавил еще на проверку вывод type(d1) == d1.__class__ - выдает True, т.е. в принципе выглядит как одно и то же…

Офлайн

#8 Май 11, 2019 17:12:07

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Подскажите по преобразованию типов в классах

Egorro13
т.е. в принципе выглядит как одно и то же…
питон - язык с долгой историей, он неоднократно изменялся и весьма существенно. Когда-то давно, в питоне существовали только классы, которые сейчас называются “классы старого стиля” для них это утверждение неверно

fish-pc% python2
Python 2.7.16 (default, Mar 11 2019, 18:59:25)
[GCC 8.2.1 20181127] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class X:
... pass
...
>>> x = X()
>>> x.__class__
<class __main__.X at 0x7fdd1ffb2c18>
>>> type(x)
<type 'instance'>
>>> type(x) == x.__class__
False

Если хотите получить класс неизвестного вам объекта, надежнее использовать .__class__, потому что он возвращает одно и то же, как для новых, так и для старых объектов. Кроме того, не надо забывать про наследование, для проверки типов в иерархии объектов используют isinstance и issubclass. type не надо использовать, если вы не занимаетесь метапрограммированием.



Офлайн

#9 Май 11, 2019 18:45:04

lerr
Зарегистрирован: 2018-07-22
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Подскажите по преобразованию типов в классах

FishHook, Egorro13
Благодарю. С этим, теперь понятно.

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version