Изменить представление объекта Python

В Python типы данных (например, int, float) представляют собой значение, но также имеют встроенные атрибуты / функции / и т. Д.

In [1]: a = 1.2 In [2]: a Out[2]: 1.2 In [3]: a.is_integer() Out[3]: False 

Возможно ли воспроизвести это поведение в Python, например, определить класс:

 class Scalar: def __init__(self, value) self.value = value # other code .... s = Scalar(1.2) 

где я мог бы вернуть s 1.2 (вместо ввода s.value ) и делать такие вещи, как a = s -> a = 1.2 ? Самое близкое, что я могу получить от этого поведения, добавляет что-то вроде:

 def __getitem__(self, key=None): return self.value 

и используя a = s[()] , но это выглядит не очень хорошо.

где я мог бы вернуть s 1.2 (вместо ввода s.value)

В консоли? Затем реализуем метод __repr__ .

a = s -> a = 1,2

Чтобы избежать использования значения a = s.value , вы можете реализовать __call__ и вызвать объект:

 >>> class Scalar: ... def __init__(self, value): ... self.value = value ... def __repr__(self): ... return str(self.value) ... def __call__(self): ... return self.value ... >>> s = Scalar(1.2) >>> s 1.2 >>> a = s() >>> a 1.2 

Проверьте документацию о модели данных для эмуляции числовых типов .

Например:

 class Scalar: def __init__(self, value): self.value = value def __repr__(self): return str(self.value) def __call__(self): return self.value def __add__(self, other): return Scalar(self.value + other.value) def __lt__(self, other): return self.value < other.value def ___le__(self, other): return self.value <= other.value def __eq__(self, other): return self.value == other.value def __ne__(self, other): return self.value != other.value def __gt__(self, other): return self.value > other.value def __ge__(self, other): return self.value >= other.value 

Может использоваться следующим образом:

 >>> s1 = Scalar(1.2) >>> s2 = Scalar(2.1) >>> s1 + s2 3.3 >>> s1 < s2 True >>> s1 > s2 False >>> s1 != s2 True >>> s1 <= s2 True >>> s1 >= s2 False 

Существуют также __int__ и __float__ magic, которые вы можете реализовать и использовать как это (это более семантически правильно):

 >>> a = int(s) >>> a = float(s) 

Насколько я знаю, это невозможно для вашего примера a = s . Вам придется изменить поведение оператора присваивания = . Оператор присваивания на самом деле ничего не делает для объекта справа, он просто копирует ссылку на него (по крайней мере, для объекта).

В общем, можно изменить поведение встроенных операторов для ваших пользовательских классов с использованием перегрузки операторов , но Python не предоставляет такую ​​возможность для назначения ( = ) из-за того, насколько отличается от операторов, таких как добавление ( + ) и даже равенство ( == ).