【问题标题】:Is it possible to define an integer-like object in Python that can also store instance variables?是否可以在 Python 中定义一个也可以存储实例变量的类整数对象?
【发布时间】:2018-07-06 00:08:24
【问题描述】:

是否可以在 python 中定义一个数据对象,当用于数学运算或比较时,其行为类似于普通整数,但也能够存储实例变量?

换句话说,应该可以做到以下几点:

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!"

【问题讨论】:

  • 你已经试过了吗?请在此处发布您的尝试
  • 那么在添加之后,您希望hidden_object 是什么?
  • @messerbill:我不知道如何解决这个问题,所以我什么都没试过。
  • @liliscent:添加后不需要调用hidden_object,没了也没关系。我只需要它能够被添加、比较或获得hidden_object
  • 您希望5 + pseudo_integer 拥有什么类型?它应该有类型int,还是类型PseudoIntegerpseudo_integer + pseudo_integer呢?

标签: python object integer int instance-variables


【解决方案1】:

所以,以上所有答案都很好,但可能您不想重新定义所有现有方法。

通常,在 python 中,您可以子类化任何内置类(类型)。但是对于不可变类型(python 中的整数是不可变的)有点棘手。 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

通常,您应该重新加载__init__ 方法,但是对于不可变基,您应该使用__new__。你可以在corresponding docs section阅读更多关于数据模型的信息

只有当您需要单一签名来构建您的对象时,所有这些都是可行的。如果可以进行 1 次创建调用,以及使用属性填充对象的专用调用 - 您只需要 Kevin's answer

【讨论】:

  • 如果希望PseudoInt(5) + 3 的结果为PseudoInt,OP 仍然必须覆盖现有方法,如__add__
  • 是的。这同样适用于就地数学,例如PseudoInt(5) += 4 将返回 9。但我想,这就是 OP 想要的 - 类似 int 的对象。要使用数学运算返回相同的类,应该重新加载__方法,你是对的。
  • 我希望PseudoInt(5) += 4SyntaxError</nitpick>
【解决方案2】:

是的,是的。您可以创建自己的自定义类。 Python 有许多神奇的方法可以帮助您归档。

检查代码:

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)

或者你可以只从 int 继承,在创建实例后,你可以为继承的 int 对象分配属性。不能直接给 int 赋值属性,因为 int 不支持项赋值:

class PseudoInteger(int):
    pass

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

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

【讨论】:

  • 谢谢!这对我很有帮助。
【解决方案3】:

你只需要一个类即可:

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)

打印出来:

10
8

你必须自己添加你需要的其他操作(除法,减法,eq,...) :)

【讨论】:

  • 嗨,非常感谢,这看起来很有希望。我有一个问题:这是否也可能无需手动定义所有这些方法,如 add 、 sub 、 eq 、 gt 等?所以基本上它从“原始” Integer 类继承了所有这些方法,我只是添加了我需要的实例变量和方法?
  • @MauriceMeyer,您实际上指的是显示如何做到这一点的帖子,而不是为什么它不可能;)
【解决方案4】:

研究为您的PseudoInteger 类实现__add____eq__ 方法

【讨论】:

  • 谢谢!这对我很有帮助。
猜你喜欢
  • 2020-09-12
  • 2021-05-09
  • 2019-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多