关于reference:在python中模拟一个int

Emulate an int in python

我想定义一个与int行为完全相同的对象,它有一些微小的区别。考虑班级

1
2
3
class MyInt:
  def __init__(self, num):
    self.num = num

我需要启用以下行为:当MyInt分配给另一个变量时,操作结果是分配MyInt.num而不是整个类,即

1
2
3
4
i = MyInt(10)
a = i
print(type(a)) # <class 'int'>
print(a)       # 10

换句话说,a=i产生a= i.numMyInt的所有其他功能应与int完全相同,并应用于MyInt.num上,如i += 1应等同于i.num +=1

我想这可以通过让MyInt继承int和利用__getattr____setattr__来实现。但是,我不确定用什么方法来获取Python中变量的值,以便实现所需的功能。

免责声明:我需要这样做,以便在函数内部全局修改变量。我知道不建议这样做,但这是我唯一的选择。我也不能用global


你不能那样做。python中没有允许您调整分配的挂钩。

绑定对象的方法有很多种,对于python,i = MyInt(10)a = i之间完全没有区别。这两者都是赋值,首先执行右侧表达式的结果,然后以特定名称存储对结果的引用。由于i生成了对MyInt(10)已经生成的同一对象的引用,因此您最终得到了对单个实例的两个不同名称的引用。

但是,[i]也存储了一个引用,现在在一个列表对象中。for target_name in (i, i):也是如此(3个引用,首先是一个有两个引用的元组,然后是target_name,当循环执行时,它像这样绑定了两次,而没有任何东西提前退出循环)。我计算了至少8种在Python中绑定对象的方法。

在大多数情况下,可以使MyInt像整数一样工作;有许多特殊的方法可以模拟数字类型,从而实现这一点。甚至还有一个numbers.Integral抽象基类可以用作起点。这些为您提供了许多预先实现的特殊方法,但是您仍然需要实现一些抽象方法,但是:

1
2
3
>>> from numbers import Integral
>>> sorted(Integral.__abstractmethods__)
['__abs__', '__add__', '__and__', '__ceil__', '__eq__', '__floor__', '__floordiv__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__neg__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rtruediv__', '__rxor__', '__truediv__', '__trunc__', '__xor__']

由于任何不可实例化的子类,这些子类会立即向您反馈是否遗漏了这些方法。

已经提供的方法有:

1
2
3
>>> from numbers import Number
>>> sorted(n for n in dir(Integral) if n not in Integral.__abstractmethods__.union(dir(Number)))
['__bool__', '__complex__', '__divmod__', '__float__', '__index__', '__rdivmod__', '__rsub__', '__sub__', 'conjugate', 'denominator', 'imag', 'numerator', 'real']

你真的想提供一个合适的__hash__方法。