Package: autorepr
Now with Python 3 support!OverviewPython makes classes easy, but__repr__methods hard. Did you forget to
referenceselfagain? Probably. Did have you thought to yourself “eh, this
class is real simple, it doesn’t need a repr”? Without a doubt. Was production
taken down three times last week because your__str__returned unicode? …
no? Maybe that’s just me.autoreprmakes it simple to build expressive, safe, and correct,__repr__,__str__,__unicode__, and__bytes__methods in a
single line each.Withautorepr, you get the repers you want, without worrying about the
fiddly bits (like encoding and decoding), leaving you to focus on your project:>>>fromautoreprimportautorepr,autotext>>>classPerson(object):...name=u"Alex ☃"...height=123.456......__repr__=autorepr(["name","height:0.1f"])...__str__,__unicode__=autotext("{self.name}({self.height:0.0f}cm)")...>>>p=Person()>>>repr(p)"<__main__.Person name=u'Alex\\u2603' height=123.5 at 0x...>">>>unicode(p)u'Alex\u2603(123 cm)'>>>str(p)'Alex\xe2\x98\x83(123 cm)'Installation$ pip install autoreprUsageautoreprexposes two main functions:autorepr, which builds a Python-esque__repr__string by passing
either astr.format-style string, or a list of attributes which should be
included in aname=valuelist:autorepr(["name", "height:0.1f"]) -->
    "<pkg.Person name=u'Alex \u2603' height=123.5 at 0x...>"
autorepr("{self.id} name={self.name!r}") -->
    "<pkg.Person 123 name=u'Alex \u2603' at 0x...>"autotext, which usesautostrandautounicodeto create__str__and__unicode__methods in a Python 2 + 3 friendly way:__str__, __unicode__ = autotext("{self.name} ({self.height!d} cm)") -->
    str: 'Alex \xe2\x98\x83 (123cm)'
    unicode: u'Alex \u2603 (123cm)'And three secondary functions -autostr,autounicode, andautobytes- which build__str__,__unicode__, and__bytes__functions, respectively. The functions will do their best to avoid Unicode
encoding / decoding errors, and will generally Do The Right Thing, even if the
inputs aren’t necessarily sensible.Note: the examples shown here are Python 2, but everything works equally well
under Python 3.>>>fromautoreprimportautorepr,autotext,autostr,autounicode>>>classPerson(object):...name=u"Alex ☃"...height=123.456......__repr__=autorepr(["name","height:0.1f"])...__str__,__unicode__=autotext("{self.name}({self.height:0.0f}cm)")...>>>p=Person()>>>repr(p)"<__main__.Person name=u'Alex\\u2603' height=123.5 at 0x...>">>>unicode(p)u'Alex\u2603(123 cm)'>>>str(p)'Alex\xe2\x98\x83(123 cm)'Notice thatautostrandautorepr(as called here throughautotext)
are intelligent about converting to/from unicode (decoding/encoding as UTF-8)
as necessary:>>>p.name=u"unicode: ☃">>>unicode(p)u'unicode:\u2603(123 cm)'>>>str(p)'unicode:\xe2\x98\x83(123 cm)'>>>p.name='utf-8 bytes:\xe2\x98\x83'>>>unicode(p)u'utf-8 bytes:\u2603(123 cm)'>>>str(p)'utf-8 bytes:\xe2\x98\x83(123 cm)'Note:autostrandautoreprwon’t crash on invalid UTF-8 (for example,
ifautounicodeis asked to turn binary data into unicode), but the result
isundefinedand may not be desirable.Additional properties can be passed in askwargs, which will be called with
the instance as a parameter:>>>name_with_len=autostr("{self.name}length={len}",...len=lambdaself:len(self.name))...>>>p.name='Alex'>>>name_with_len(p)'Alex length=4'This works withautorepr’s list mode too:>>>repr_with_len=autorepr(["name","len"],...len=lambdaself:len(self.name))...>>>repr_with_len(p)"<__main__.Person name='Alex' len=4 at 0x...>"If a regular format string is passed toautorepr, it will use that instead
of the generated string:>>>repr_with_str=autorepr("{self.name!r}")>>>repr_with_str(p)"<__main__.Person 'Alex' at 0x...>"And of course, if you don’t want your__repr__to be wrapped in<ClassName...>, you can useautostr:>>>repr_with_autostr=autostr("Person({self.name!r})")>>>repr_with_autostr(p)"Person('Alex')"Format specifications can also be passed toautoreprif the default of!ris undesirable (for example, truncating floats):>>>with_fmt_spec=autorepr(["duration:0.1f","addr:x","type!s"],...duration=lambdax:123.456,...addr=lambdax:0xabc123,...type=lambdax:"foo")>>>with_fmt_spec(None)'<....NoneType duration=123.5 addr=abc123 type=foo at 0x...>'