Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

279
Visualizações
Overload all arithmetic operators in Python

Suppose I build a class that basically represents a number plus some fancy stuff. Instances of that class should behave like numbers in any arithmetic/mathematical operation.

I could overload all numeric operators in that class, but is there no shorter solution?

The class basically looks like:

class MyFancyNumber:
    def __init__(self, num, info):
        self.num = num # the actual number
        self.info = info # some more info, or other data
    def doFancyStuff(self):
        # does something fancy
    def __add__(self, other):
        return self.num + other # same pattern for all numeric functions
over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

What about this?

class MyFancyNumber(int):
    def __new__(cls, num, info=None):
        return super(MyFancyNumber, cls).__new__(cls, num)
    def __init__(self, num, info=None):
        self.num = num
        self.info = info
>>> MyFancyNumber(5)
5
>>> MyFancyNumber(5) + 2
7
>>> MyFancyNumber(5) / 4
1
>>> MyFancyNumber(5) * 0.5
2.5
>>> MyFancyNumber(5) - 7
-2
>>> MyFancyNumber(5, 'info').info
'info'

I guess based on the above, you can figure out what you need.

over 4 years ago · Santiago Trujillo Relatório

0

I don't endorse this as being particularly idiomatic, but...

Assuming all of your function definitions behave identically, like "just invoke the base behavior of the self.num class and apply all the non-self arguments to it", then you can loop through all the function names you want to define, and create each one using setattr. Example:

class MyFancyNumber(object):
    def __init__(self, num, info):
        self.num = num
        self.info = info
    def __repr__(self):
        return "MyFancyNumber({}, {})".format(repr(self.num), repr(self.info))

def make_func(name):
    return lambda self, *args: MyFancyNumber(getattr(self.num, name)(*args), self.info)

for name in ["__add__", "__sub__", "__mul__", "__div__", "__invert__", "__neg__", "__pos__"]:
    setattr(MyFancyNumber, name, make_func(name))

x = MyFancyNumber(50, "hello")
print(x + 10)
print(x - 10)
print(x * 10)
print(x / 10)
print(~x)
print(-x)
print(+x)

Result:

MyFancyNumber(60, 'hello')
MyFancyNumber(40, 'hello')
MyFancyNumber(500, 'hello')
MyFancyNumber(5, 'hello')
MyFancyNumber(-51, 'hello')
MyFancyNumber(-50, 'hello')
MyFancyNumber(50, 'hello')

Edit: I wasn't sure whether you wanted the result of arithmetic to be a MyFancyNumber or a regular built-in numerical type, but either way, the implementation is pretty similar:

class MyFancyNumber(object):
    def __init__(self, num, info):
        self.num = num
        self.info = info
    def __repr__(self):
        return "MyFancyNumber({}, {})".format(repr(self.num), repr(self.info))

def make_func(name):
    return lambda self, *args: getattr(self.num, name)(*args)

for name in ["__add__", "__sub__", "__mul__", "__div__", "__invert__", "__neg__", "__pos__"]:
    setattr(MyFancyNumber, name, make_func(name))

x = MyFancyNumber(50, "hello")
print(x + 10)
print(x - 10)
print(x * 10)
print(x / 10)
print(~x)
print(-x)
print(+x)

Result:

60
40
500
5
-51
-50
50
over 4 years ago · Santiago Trujillo Relatório

0

No, you have to define all the arithmetic operators otherwise how would Python know what to do with them. Don't forget you also need the reverse operators like __radd__.

Also the code you've written returns an int for x+1. Did you mean that or did you want adding a fancy number to return another fancy number?

You could just subclass int or float. Then you don't have to reimplement the operators but you'll still lose the special nature whenever you operate on a value.

A better solution would just be to have the numeric value in an attribute and convert to numbers explicitly when that's what you want. You can use __int__() and __float__() to implement the conversion.

The documentation covers what you need to do if you really do want to emulate a numeric type: for Python 3.x https://docs.python.org/3/reference/datamodel.html?highlight=int#emulating-numeric-types or for Python 2.x https://docs.python.org/2/reference/datamodel.html?highlight=int#emulating-numeric-types

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda