Question

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.

Était-ce utile?

La solution

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 !=.

Autres conseils

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.

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'

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top