OOP Challenge in Python
Why are you using __double_underscore_prefixes for your member variable names?

Double-underscores get name-mangled by Python for the purpose of 'class-local references'. They're for when your class's implementation relies on something that you don't want subclasses to customise. This is a very rare situation, and typically happens quite late in a library's lifetime.

What double-underscore names are not for is access control. This is one of the biggest pieces of mis-information given to Python beginners.
Python doesn't have a concept of 'public' and 'private', and you shouldn't try to hack one together out of a language feature designed for something else. All your member variables should just be public by default; if you need to change an implementation detail, you can maintain your contract using properties.

If you really insist on declaring something as private, the conventional way to do that in Python is using a _single_leading_underscore. It's still not actually private, it's just a clear signal to your consumers that they shouldn't mess around with that stuff because it might change.



I also don't really like the way you're using __str__. __str__ is designed to return a meaningful description of the object, generally for the purposes of debugging (or when you wish to emulate string-like behaviour). You're using __str__ as part of the behaviour of your class (returning a formatted string in plain English).

I'd put the body of __str__ inside the talk method, and either delete __str__ altogether, or use it for something more meaningful to a person working with the code - something like this:

def __str__(self):
    return "Critter named {} with hunger {} and boredom {}".format(self.__name, self.__hunger, self.__boredom)

def talk(self):
    print("Hi, I'm " + self.__name + " and I feel " + self.mood + ".")
    self.__passTime()