Is it possible to define an integer-like object in Python that can also store instance variables?

為{幸葍}努か 提交于 2019-12-25 00:38:12

问题


Is it possible to define a data object in python that behaves like a normal integer when used in mathematical operations or comparisons, but is also able to store instance variables?

In other words, it should be possible to do the following things:

pseudo_integer = PseudoInteger(5, hidden_object="Hello World!")
print(5 + pseudo_integer) # Prints "10"
print(pseudo_integer == 5) # Prints "True"
print(pseudo_integer.hidden_object) # Prints "Hello World!"

回答1:


Yes, it is. You can create your own custom class. Python has many magic methods to help you archive that.

Check the code:

class PseudoInteger:
    def __init__(self, x, s):
        self.x = x
        self.s = s

    def __add__(self, num):
        return self.x + num

    def __eq__(self, num):
        return self.x == num


a = PseudoInteger(5, 'hello, world')
print(a + 3)
print(a == 5)
print(a == 2)

Or you can just inherit from int, after creating an instance, you are able to assign attributes to the inherited int object. You can't assign attributes to int directly, because int does not support item assignment :

class PseudoInteger(int):
    pass

a = PseudoInteger(5)
a.hidden = 'hello, world'

print(a)
print(a == 5)
print(a + 3)
print(a.hidden)



回答2:


You simply need a class for this:

class PseudoInteger(object):
    def __init__(self, num, hidden=None):
        self.num = num
        self.hidden = hidden

    def __add__(self,  otherVal):
        if isinstance(otherVal, PseudoInteger):
            return self.num + otherVal.num
        else:
            return self.num + otherVal

p = PseudoInteger(4, 'Tiger')
q = PseudoInteger(6, 'lion')

print (p+q)
print (p+4)

This prints out:

10
8

You have to add the other operations (division, substraction, eq, ...) you need to the class on your own :)




回答3:


So, all answers above is fine, but probably you don't want to re-define all existing methods.

Normally, in python you can just subclass any built-in class (type). But with immutable types (and integers in python is immutable) is slightly tricky. TL;DR:

class PseudoInt(int):
    def __new__(cls, x, hidden, *args, **kwargs):
        instance = int.__new__(cls, x, *args, **kwargs)
        instance.hidden = hidden
        return instance

x = PseudoInt(5, 'secret')
x.hidden  # 'secret'
x + 4  # 9
x * 3  # 15

Normally, you should reload __init__ method, but with immutable bases you should use __new__. You can read more about data model in corresponding docs section

All this is viable only if you need single signature for constructing your object. If its fine to have 1 call for creating, and dedicated calls to populate object with attributes - Kevin's answer is all you need




回答4:


Look into implementing the __add__ and __eq__ methods for your PseudoInteger class



来源:https://stackoverflow.com/questions/48464960/is-it-possible-to-define-an-integer-like-object-in-python-that-can-also-store-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!