Reputation: 60014
I want
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
...
What do use instead of ???
to ensure that the assert
never fails?
(With Lisp, I could create _my_unique
with (cons nil nil)
and used eq
in assert
).
PS. Use case: I will put _my_unique
in a dict
, so I want it to be equal to itself, but I do not want it to be equal (in the dict
collision sense) to anything passed in from the outside.
Upvotes: 6
Views: 4865
Reputation: 15877
This is a mildly confusing question, as it seems to mix a bunch of concepts without purpose. For one thing, most any object in Python is unique, but there may be multiple ways to reach them. The operator to check identities is not !=
(inequality) but is not
. Unlike Java, Python does not require you to put things in a class, and does not implicitly look in self
(which they know as implicit this
). cons
from Lisp is used to construct pairs which frequently form singly linked lists, a structure that's unusual in Python because we use dynamic reference arrays known as lists. Lists are mutable, and thus constructing one using list()
or []
will produce a unique object.
So, while it is rather pointless, one way to write a function producing functions that perform the useless assert might be:
def createfunc():
mylist=[]
def subfunc(x):
assert x is not mylist
return subfunc
Each call to createfunc()
returns a new function with its own mylist
. However, the object being unique doesn't make it impossible to reach:
f=createfunc()
f(f.func_closure[0].cell_contents) # raises AssertionError
Regarding the PS, to be relevant to dict
collissions, your object must also be hashable, which makes object()
a better choice than list()
for the unique object.
Upvotes: -3
Reputation: 385970
If what you're asking is "how do I make _my_unique unique for each instance of MyClass", you could simply create a new, empty object in the constructor.
For example:
>>> 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>
If you want to hide _my_unique
, give it two underscores. This way, nobody can accidentally get at the value. It's not impossible, but they would need to work a little harder to get at the value. This is called name mangling, and you can read more about it here: 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'
Upvotes: 0
Reputation: 250951
You can use object()
.
Return a new featureless object.
object
is a base for all new style classes. It has the methods that are common to all instances of new style classes.
Upvotes: 3
Reputation: 251383
You can use object()
, but this won't make the assert "never fail". It will still fail if you call myFunc
and pass MyClass.my_unique
as the object. Also, if you want to test whether it's the same object, use arg is not my_unique
rather than !=
.
Upvotes: 7