简体   繁体   English

在python中模拟一个int

[英]Emulate an int in python

I want to define an object which has the exact same behavior as an int, with a few tiny differences. 我想定义一个对象,其行为与int完全相同,但有一些细微的差别。 Consider the class 考虑上课

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

I need to enable the following behavior: when MyInt is assigned to another variable, the operation results to assigning MyInt.num instead of the whole class, ie 我需要启用以下行为:当MyInt被分配到另一个变量,操作结果分配MyInt.num而不是整个类,即

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

In other words, a=i results in a= i.num . 换句话说, a=i导致a= i.num All other functionality of MyInt should be exactly the same as int and applied on MyInt.num , eg i += 1 should be equivalent to i.num +=1 的所有其他功能MyInt应该是完全一样int和施加在MyInt.num ,例如i += 1应相当于i.num +=1

I guess that this can be accomplished by making MyInt inherit from int and making use of __getattr__ and __setattr__ . 我猜这可以通过使MyIntint继承并使用__getattr____setattr__ However, I am not sure what method is used to fetch the value of a variable in python so that I can achieve the desired functionality. 但是,我不确定使用哪种方法来获取python中变量的值,以便实现所需的功能。

Disclaimer: I need this so that I can modify a variable globally inside a function. 免责声明:我需要这样做,以便可以在函数内部全局修改变量。 I am aware this is not recommended, but it is my only option. 我知道不建议这样做,但这是我唯一的选择。 Also I cannot use global . 我也不能使用global

You can't do that. 你不能那样做。 There are no hooks in Python that let you adjust assignments. Python中没有钩子可让您调整分配。

There are any number of ways of binding an object, and to Python, there is no difference, at all , between i = MyInt(10) and a = i . 有任何数目的结合的对象的方法,和对Python, 没有差别, 在所有的 ,之间i = MyInt(10)a = i Both are assignments where the result of the expression on the right-hand side are executed first , then a reference to the result is stored under a specific name. 两者都是赋值,其中首先执行右侧表达式的结果,然后以特定名称存储对该结果的引用。 Since i produces the a reference to the same object already produced by MyInt(10) , you end up with 2 references, with different names, to a single instance. 由于i产生了对MyInt(10)已经产生的同一对象的引用,因此您最终对单个实例有2个引用,它们具有不同的名称。

But [i] also stores a reference, now in a list object. 但是[i]现在也将引用存储在列表对象中。 So does for target_name in (i, i): (3 references, first in a tuple with two references, then target_name , which is bound twice like this when the loop executes and nothing exits the loop early). for target_name in (i, i):for target_name in (i, i):这样for target_name in (i, i): (3个引用,首先是在具有两个引用的元组中,然后是target_name ,当循环执行时,它被绑定两次,这样循环就不会退出了)。 I count at least 8 different ways of binding objects in Python. 我数了至少8种不同的 Python 绑定对象方式

You can make MyInt work like an integer in most cases; 在大多数情况下, 可以使MyInt像整数一样工作。 there are a number of special methods to emulate numeric types that let you accomplish this. 许多模拟数字类型的特殊方法可以帮助您完成此任务。 There is even a numbers.Integral abstract base class you can use as a starting point. 甚至有一个numbers.Integral抽象基类 ,你可以作为一个起点使用。 These provide you with a number of those special methods pre-implemented, but you do have to still implement a number of abstract methods, however: 这些为您提供了许多预先实现的特殊方法,但是您仍然必须实现许多抽象方法:

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

Since any subclass that doesn't can't be instantiated, these give you instant feedback on whether or not you missed any of those methods. 由于无法实例化任何无法实例化的子类,因此这些子类可为您提供有关是否错过任何一种方法的即时反馈。

Methods already provided are: 已经提供的方法是:

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

and you really want to provide a suitable __hash__ method . 并且您真的想提供一种合适的__hash__方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM