Skip to content

Instantly share code, notes, and snippets.

@floer32
Last active August 29, 2015 13:55
Show Gist options
  • Save floer32/8742916 to your computer and use it in GitHub Desktop.
Save floer32/8742916 to your computer and use it in GitHub Desktop.
A mixin that gives an OK default for `__repr__`. Format is like "ClassName(attributeA='foo', attributeB='bar', propertyA='baz', propertyB='quux')" where each of those values is the `repr()` of the value.
class EasyReprMixin(object):
""" A mixin that gives an OK default for `__repr__`.
I mix this into classes with instances that are static after creation,
i.e. with properties telling you about their contents. Wrappers for
data usually.
"""
def __repr__(self):
attributes = [
(key, val) for key, val in self.__dict__.iteritems()
if not matches_pattern_for_internal_methods(key)
]
properties = [
(key, val) for key, val in self._properties().iteritems()
if not matches_pattern_for_internal_methods(key)
]
attributes_and_properties = merge(attributes, properties)
repr_string = "{class_name}({attributes})".format(
class_name=self.__class__.__name__,
attributes=", ".join([
"=".join([key, repr(value)]) for key, value in attributes_and_properties
])
)
return repr_string
def _properties(self):
class_items = self.__class__.__dict__.iteritems()
return {
key: getattr(self, key)
for key, value in class_items
if isinstance(value, property)
}
def matches_pattern_for_internal_methods(string):
""" Check whether the string looks like the name of a Python "internal"/"magic" method.
"""
return string.startswith('__') and string.endswith('__')
def name_of_callable(callable):
try:
return callable.__class__.__name__
except AttributeError:
return callable.__name__
except:
return repr(callable)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment