如何创建唯一对象?

时间:2014-03-25 18:01:25

标签: python cons

我想要

class MyClass(object):
    _my_unique = ????      # if this were lisp, I would have written (cons nil nil) here

    def myFunc (self, arg):
        assert arg != _my_unique    # this must never fail
        ...

使用什么代替???来确保assert永不失败?

(使用Lisp,我可以使用_my_unique创建(cons nil nil)并在eq中使用assert

PS。使用案例:我会将_my_unique放在dict中,所以我希望它与自己相等,但我不希望它相等(在dict碰撞意义上)从外面传来的任何东西。

4 个答案:

答案 0 :(得分:4)

您可以使用object(),但这不会使断言“永不失败”。如果您调用myFunc并将MyClass.my_unique作为对象传递,它仍然会失败。此外,如果您想测试它是否是同一个对象,请使用arg is not my_unique而不是!=

答案 1 :(得分:2)

您可以使用object()

  

返回一个新的无特征对象。 object是所有新风格的基础   类。它具有所有新实例共有的方法   风格课。

答案 2 :(得分:0)

如果您要问的是“我如何为每个MyClass实例创建_my_unique”,那么您只需在构造函数中创建一个新的空对象。

例如:

>>> class MyClass(object):
...     def __init__(self):
...         self._my_unique = object()
... 
>>> foo=MyClass()
>>> bar=MyClass()
>>> foo._my_unique
<object object at 0x100ce70c0>
>>> bar._my_unique
<object object at 0x100ce7090>

如果要隐藏_my_unique,请给它两个下划线。这样,没有人能够意外地获得价值。这并非不可能,但他们需要更加努力才能获得价值。这称为 name mangling ,你可以在这里阅读更多相关信息:http://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references

>>> class MyClass(object):
...     def __init__(self):
...         self.__my_unique = object()
... 
>>> foo=MyClass()
>>> foo.__my_unique
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'MyClass' object has no attribute '__my_unique'

答案 3 :(得分:-2)

这是一个有点令人困惑的问题,因为它似乎混合了一堆没有目的的概念。首先,Python中的大多数对象都是唯一的,但可能有多种方法可以实现它们。检查身份的运营商不是!=(不等),而是is not。与Java不同,Python不要求你把东西放在一个类中,也不要隐式查看self(他们知道它是隐式的this)。来自Lisp的cons用于构造经常形成单链表的对,这种结构在Python中是不常见的,因为我们使用称为列表的动态引用数组。列表是可变的,因此使用list()[]构建一个将生成一个唯一的对象。

所以,虽然它是毫无意义的,但编写一个生成执行无用断言的函数的函数的一种方法可能是:

def createfunc():
  mylist=[]
  def subfunc(x):
    assert x is not mylist
  return subfunc

createfunc()的每次调用都会返回一个具有自己的mylist的新函数。但是,对象的独特性并不会使其无法达到:

f=createfunc()
f(f.func_closure[0].cell_contents)   # raises AssertionError

关于PS,要与dict碰撞相关,您的对象也必须是hashable,这使object()成为唯一对象的list()更好的选择。