在 python 中是否可以强制为包含 -5 到 256 之间整数的变量设置唯一 ID?

Possible to force unique IDs to variables containing integers between -5 and 256 in python?

我有一个 class 有几个命名属性。我希望能够将 classes 属性之一传递给自身,并能够具体确定传递了哪个属性。

下面是我如何做的一个简单示例(使用 "is" 运算符),直到我发现特殊的缓存变量 ID 用于 -5 到 256 之间的整数值。

class AClass:
    def __init__(self, one, two, three):
        self.one = one
        self.two = two
        self.three = three

    def getIndex(self, attribute):
        if attribute is self.one:
            return 1
        elif attribute is self.two:
            return 2
        elif attribute is self.three:
            return 3

    def setByIndex(self, i, value):
        if i == 1:
            self.one = value
        elif i == 2:
            self.two = value
        elif i == 3:
            self.three = value

    def setByAttrib(self, attribute, value):
        i = self.getIndex(attribute)
        self.setByIndex(i, value)


object = AClass(0, 0, 0)

object.setByAttrib(object.three, 10)

在上面的例子中,意图是将object.three设置为10。但是,由于所有属性都指向整数 0 的缓存位置,getIndex 函数将对其中任何一个求值为真,而 object.one(最先出现的)将设置为 10.如果使用值 257、257、257 初始化对象,功能大概会如预期的那样。

所以问题是,有没有办法:

a) 强制系统为这些属性分配非缓存的唯一内存位置(即使它们设置在 -5 和 256 之间),或

b) 使用其他方法检查作为参数传递的属性本身是否唯一?

编辑:

因为它被问过几次,我使用这个范例的原因之一是 python 中缺少指针。在上面的例子中,setByIndex 函数可能会对属性做一些复杂的工作。与其为每个变量编写多个相同的函数(例如 setOne、setTwo、setThree),我可以编写一个通过索引检索和设置的通用函数(索引基本上就像一个指针)。是的,我可以将属性值作为参数和 return 新设置值传递,并在已知特定属性的范围内进行赋值,但我已经 return 了一个值。是的,我可以 return 一个列表,但它增加了更多的复杂性。

我确实意识到有更好的方法来实现我需要的东西(例如,属性和索引号的键值对),但是实现起来需要做很多工作(数以千计的更改)。如果有办法使用可变 ID 作为我的唯一标识符并继续使用 "is" 运算符(或类似的),我就不需要做太多更改。虽然看起来不太可能。欣赏 comments/responses.

我不会担心内存位置,它们只是这里的一个实现细节。这实际上是关于函数设计的,所以如果你想设置 object.three,那么就这样做,否则,如果你想的话,你可以创建一个到索引的映射:

class MyClass:
    def __init__(self, *args):
        self.one, self.two, self.three, *_ = args

    # get an object by it's index
    def get_by_index(self, index):
        # here's how you could create such a mapping
        opts = dict(zip((1, 2, 3), ('one', 'two', 'three')))

        try:
            return getattr(self, opts[index])
        except KeyError as e:
            raise ValueError(f"Improper alias for attribute, select one of {', '.join(opts)}") from e

    # if you want to set by an index, then do that this way
    def set_by_index(self, index, val):
        opts = dict(zip((1, 2, 3), ('one', 'two', 'three')))

        try:
            setattr(self, opts[index], val)
        except KeyError as e:
            raise ValueError(f"Improper alias for attribute, select one of {', '.join(opts)}") from e



# otherwise, just set the attribute by the name
a = MyClass(0, 0, 0)
a.three = 55


事实是,你是对的,is 将以相同的方式查看三个 0,因为它从一开始就没有复制该数据。 one, two, three 指向相同的数据,因为它们被分配了相同的数据。再次分配该属性后,您实际上将该属性重新绑定到 值,而不是更新现有值。

重要的是,不用担心哪里内存用于此实现,只需针对属性明确设置