我想要
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
碰撞意义上)从外面传来的任何东西。
答案 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()
更好的选择。