2015-08-07 7 views
3

В Python, типы данных (например, INT, поплавок) и представляет ценность, но и имеют некоторые встроенные атрибуты/функция/и т.д.:Изменить представление объекта Python

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[()], но это выглядит не очень хорошо.

+0

Возможный дубликат [Python property call (http://stackoverflow.com/questions/13029254/python-property-callable) – TigerhawkT3

+1

В частности, см. фрагмент с классом 'WeirdInteger'. – TigerhawkT3

+2

Это не общее решение, но вы можете сделать свой класс Scalar в вашем примере так, как вы хотите, просто подклассифицируя float (или int или любой другой скалярный тип, который вы хотели бы имитировать). 'class Scalar (float): pass; s = Scalar (1.2) ' –

ответ

4

where I could have s return 1.2 (instead of typing 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 

Обратитесь к документации о data model on emulating numeric types.

Например:

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__ магические методы, которые можно реализовать и использовать, как это (это более семантически правильный):

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

Ну, '__call__' избавляется от одного набора скобок, так что это улучшение ;-) Если я не могу найти другое решение, и предложения сверху (с использованием' class Scalar (float) ') не работают, это может быть приемлемым решением. – Bart

+0

'__repr__' собирается жаловаться, если вы попытаетесь вернуть что-либо, кроме строки:' TypeError: __repr__ возвращен не-string (type float) '. Это также не повлияет на операции присваивания ('a = s'), как описано в вопросе. –

1

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

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

+1

Почему этот ответ становится downvoted, когда он говорит по существу то же самое, что и все ответы [здесь] (https://stackoverflow.com/questions/11024646/is-it-possible-to-overload-python-assignment)? –

+0

@ Two-BitAlchemist - Это говорит о том, что «это невозможно», когда базовое подклассы делает это возможным. – TigerhawkT3

+3

@ TigerhawkT3 Вид ... Это не дает возможности в общем случае, и нет смысла подклассировать, скажем, строку, если это то, что вам нужно. Только то, что вам нужно. –

Смежные вопросы