首页 > 解决方案 > 在python中模拟一个int

问题描述

我想定义一个与 int 具有完全相同行为的对象,但有一些微小的差异。考虑班级

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

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

i = MyInt(10)
a = i
print(type(a)) # <class 'int'>
print(a)       # 10

换句话说,a=i结果是a= i.num。的所有其他功能MyInt应与 完全相同int并应用于MyInt.num,例如i += 1应等效于i.num +=1

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

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

标签: pythonreferenceintbuilt-in

解决方案


你不能那样做。Python 中没有可让您调整分配的钩子。

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

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

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

>>> 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__']

由于任何不能实例化的子类,这些都会给您即时反馈您是否错过了任何这些方法。

已经提供的方法有:

>>> 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__方法


推荐阅读