Класс Python с целочисленной эмуляцией - PullRequest
5 голосов
/ 28 октября 2009

Приведен следующий пример:

class Foo(object):
    def __init__(self, value=0):
        self.value=value

    def __int__(self):
        return self.value

Я хочу иметь класс Foo , который действует как целое число (или число с плавающей точкой). Поэтому я хочу сделать следующие вещи:

f=Foo(3)
print int(f)+5 # is working
print f+5 # TypeError: unsupported operand type(s) for +: 'Foo' and 'int'

Первый оператор print int(f)+5 работает, потому что есть два целых числа. Второй сбой, потому что мне нужно реализовать __add__, чтобы выполнить эту операцию с моим классом.

Итак, чтобы реализовать целочисленное поведение, я должен реализовать все методы целочисленной эмуляции. Как я мог обойти это. Я пытался унаследовать от int, но эта попытка не удалась.

Обновление

Наследование от int завершается неудачно, если вы хотите использовать __init__:

class Foo(int):
    def __init__(self, some_argument=None, value=0):
        self.value=value
        # do some stuff

    def __int__(self):
        return int(self.value)

Если вы затем позвоните:

f=Foo(some_argument=3)

вы получите:

TypeError: 'some_argument' is an invalid keyword argument for this function

Протестировано с Python 2.5 и 2.6

Ответы [ 3 ]

7 голосов
/ 28 октября 2009

В Python 2.4+ наследование от int works:

class MyInt(int):pass
f=MyInt(3)
assert f + 5 == 8
5 голосов
/ 24 ноября 2009

Вам нужно переопределить __new__, а не __init__:

class Foo(int):
    def __new__(cls, some_argument=None, value=0):
        i = int.__new__(cls, value)
        i._some_argument = some_argument
        return i

    def print_some_argument(self):
        print self._some_argument

Теперь ваш класс работает как положено:

>>> f = Foo(some_argument="I am a customized int", value=10)
>>> f
10
>>> f + 8
18
>>> f * 0.25
2.5
>>> f.print_some_argument()
I am a customized int

Дополнительную информацию о переопределении new можно найти в Объединение типов и классов в Python 2.2 .

2 голосов
/ 28 октября 2009

Попробуйте использовать последнюю версию Python. Ваш код работает в 2.6.1.

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