Question: There are several standard ways to make a class hashable, for example (borrowing from [SO](https://stackoverflow.com/questions/2909106/python-whats-a-correct-and-good-way-to-implement-hash/2909119#2909119)):

```
# assume X has 2 attributes: attr_a and attr_b
class X:
  def __key(self):
    return (self.attr_a, self.attr_b)

  def __eq__(x, y):
    return isinstance(y, x.__class__) and x.__key() == y.__key()

  def __hash__(self):
    return hash(self.__key())

```

Now suppose I have many classes that I want to make hashable. They are all immutable, with immutable attributes, and hashing all these attributes in bulk is acceptable (for a class with too many attributes, we would only want to hash a few attributes that are enough to avoid most collisions). Can I avoid writing `__key()` method by hand for every class?

Would it be a good idea to make a base class that defines `__key()`, `__eq__`, and `__hash__` for them? In particular, I'm not sure whether finding all the instance attributes that should go into `__hash__` is doable. I know this is [generally impossible](https://stackoverflow.com/a/191029/336527), but in this case we can assume more about the object (e.g., it's immutable - after `__init__` is finished, its attributes are all hashable, etc.).

(If the inheritance hierarchy won't work, perhaps a decorator would?)

Answer: 
Instances store their attributes in `self.__dict__`:

```
>>> class Foo(object):
...     def __init__(self, foo='bar', spam='eggs'):
...         self.foo = foo
...         self.spam = spam
... 
>>> f = Foo()
>>> f.__dict__
{'foo': 'bar', 'spam': 'eggs'}

```

Provided you don't store any methods on your instances, a default `.__key()` could be:

```
def __key(self):
    return tuple(v for k, v in sorted(self.__dict__.items()))

```

where we sort the items by attribute name; the `tuple()` call ensures we return an immutable sequence suitable for the `hash()` call.

For more complex setups you'd have to either test for the types returned by `values()` (skip functions and such) or use a specific pattern of attributes or repurpose `__slots__` to list the appropriate attributes you can use.

Together with your `__hash__` and `__eq__` methods, that'd make a good base class to inherit from for all your immutable classes.
You can do it if you assume conventions for your attributes. In your example,
it would be quite trivial, as your attributes starts with "attr\_" - so you coult write your \_\_key method as :

```
def __key(self):
    return tuple (getattr(self, attr) for attr in self.__dict__ if attr.startswith("attr_") )

```

As you can see - any test you can find to put on the filter condition of the generator expression would fit your needs.

A suggestion I can give you is to have your classes using Python's `__slots__` feature:
that not only will make your attribute names easy to find, as will make your imutable objects more efficient to use and with smaller memory footprint.

```
class X:
    __slots__ = ("a", "b", "c")
    def __key(self):
        return tuple (getattr(self, attr) for attr in self.__class__.__slots__ )

```

**edit**
Answering the first comment from the O.P.:

This works with inheritance, of course. If you will always use all of the object's attributes for they, you don't need the "if" part of the expression - write the function as `_key` (instead of `__key` which makes a unique name for each class internally) on a class on the top of your hierarchy, and it will work for all your classes.