Package: cheap-repr
cheap_reprThis library provides short, fast, configurable string representations, and an easy API for registering your own. It's an improvement of the standard library modulereprlib(reprin Python 2).Just use thecheap_reprfunction instead ofrepr:>>>fromcheap_reprimportcheap_repr>>>cheap_repr(list(range(100)))'[0, 1, 2, ..., 97, 98, 99]'cheap_reprknows how to handle many different types out of the box. You can register a function for any type, and pull requests to make these part of the library are welcome. If it doesn't know how to handle a particular type, the defaultrepr()is used, possibly truncated:>>>classMyClass(object):...def__init__(self,items):...self.items=items......def__repr__(self):...return'MyClass(%r)'%self.items...>>>c=MyClass(list(range(20)))>>>cMyClass([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19])>>>cheap_repr(c)'MyClass([0, 1, 2, 3, 4, 5, 6... 13, 14, 15, 16, 17, 18, 19])'Suppression of long reprscheap_repris meant to prevent slow, expensive computations of string representations. So if it finds that a particular class can potentially produce very long representations, the class will besuppressed, meaning that in future the__repr__won't be calculated at all:>>>cheap_repr(MyClass(list(range(1000))))'MyClass([0, 1, 2, 3, 4, 5, 6...94, 995, 996, 997, 998, 999])'.../cheap_repr/__init__.py:80:ReprSuppressedWarning:MyClass.__repr__istoolongandhasbeensuppressed.Registerareprfortheclasstoavoidthiswarningandseeaninformativerepragain,orincreasecheap_repr.suppression_threshold>>>cheap_repr(MyClass(list(range(1000))))'<MyClass instance at 0x1034de7f0 (repr suppressed)>'cheap_repr.suppression_thresholdrefers to the attribute on the function itself, not the module. By default it's 300, meaning that areprlonger than 300 characters will trigger the suppression.Registering your own repr functionFor example:>>>fromcheap_reprimportregister_repr>>>@register_repr(MyClass)...defrepr_my_class(x,helper):...returnhelper.repr_iterable(x.items,'MyClass([','])')...>>>cheap_repr(MyClass(list(range(1000))))'MyClass([0, 1, 2, 3, 4, 5, ...])'In general, write a function that takes two arguments(x, helper)and decorate it withregister_repr(cls). Thencheap_repr(x)whereisinstance(x, cls)will dispatch to that function, unless there is also a registered function for a subclass whichxis also an instance of. More precisely, the function corresponding to the first class in the MRO will be used. This is in contrast to the standard library modulereprlib, which cannot handle subclasses that aren't explicitly 'registered', or classes with the same name.Thehelperargument is an object with a couple of useful attributes and methods:repr_iterable(iterable, left, right, end=False, length=None)produces a comma-separated representation ofiterable, automatically handling nesting and iterables that are too long, surrounded byleftandright. The number of items is limited tofunc.maxparts(see the configuration section below).Setend=Trueto include items from both the beginning and end, possibly leaving out items
in the middle. Only do this ifiterablesupports efficient slicing at the end, e.g.iterable[-3:].Provide thelengthparameter iflen(iterable)doesn't work. Usually this is not needed.truncate(string)returns a version ofstringat mostfunc.maxpartscharacters long, with the middle replaced by...if necessary.levelindicates how much nesting is still allowed in the result. If it's 0, return something minimal such as[...]to indicate that the original object is too deep to show all its contents. Otherwise, if you usecheap_repron several items insidex, passhelper.level - 1as the second argument, e.g.', '.join(cheap_repr(item, helper.level - 1) for item in x).Exceptions in repr functionsIf an exception occurs incheap_repr, whether from a registered repr function or the usual__repr__, the exception will be caught and the cheap repr of the class will be suppressed:>>>@register_repr(MyClass)...defrepr_my_class(x,helper):...return'MyClass([%r, ...])'%x.items[0]...>>>cheap_repr(MyClass([]))'<MyClass instance at 0x10f44ec50 (exception in repr)>'.../cheap_repr/__init__.py:123:ReprSuppressedWarning:Exception'IndexError: list index out of range'inrepr_my_classforobjectoftypeMyClass.Thereprhasbeensuppressedforthistype....>>>cheap_repr(MyClass([1,2,3]))'<MyClass instance at 0x10f44ecc0 (repr suppressed)>'If you would prefer exceptions to bubble up normally, you can:Setcheap_repr.raise_exceptions = Trueto globally make all exceptions bubble up.To bubble exceptions from the__repr__of a class, callraise_exceptions_from_default_repr().Setrepr_my_class.raise_exceptions = True(substituting your own registered repr function) to make exceptions bubble from that function. The way to find the relevant function is in the next section.Configuration:Configuration for specific functionsTo configure a specific function, you set attributes on that function. To find the function corresponding to a class, usefind_repr_function:>>>fromcheap_reprimportfind_repr_function>>>find_repr_function(MyClass)<functionrepr_my_classat0x10f43d8c8>For most functions, there are two attributes available to configure, but contributors and library writers are encouraged to add arbitrary attributes for their own functions. The first attribute israise_exceptions, described in the previous section.maxpartsThe other configurable attribute ismaxparts. All registered repr functions have this attribute. It determines the maximum number of 'parts' (e.g. list elements or string characters, the meaning depends on the function) from the input that the output can display without truncation. The default value is 6. The decorator@maxparts(n)conveniently sets the attribute to make writing your own registered functions nicer. For example:>>>fromcheap_reprimportmaxparts>>>@register_repr(MyClass)...@maxparts(2)...defrepr_my_class(x,helper):...returnhelper.repr_iterable(x.items,'MyClass([','])')...>>>cheap_repr(MyClass([1,2,3,4]))'MyClass([1, 2, ...])'>>>find_repr_function(MyClass).maxparts=3>>>cheap_repr(MyClass([1,2,3,4]))'MyClass([1, 2, 3, ...])'pandasThe functions forDataFrames andSeriesfrom thepandaslibrary don't usemaxparts.
For theDataFramefunction there'smax_rowsandmax_cols. For theSeriesfunction there's justmax_rows.level and max_levelcheap_reprtakes an optional argumentlevelwhich controls the display of nested objects. Typically this decreases through recursive calls, and when it's 0, the contents of the object aren't shown. See 'Registering your own repr function' for more details. This means you can change the amount of nested data in the output ofcheap_reprby changing thelevelargument. The default value ischeap_repr.max_level, which is initially 3. This means that changingcheap_repr.max_levelwill effectively change thelevelargument whenever it isn't explicitly specified.Global configurationThese things that can be configured globally:cheap_repr.suppression_threshold, discussed in the 'Suppression of long reprs' section.The handling of exceptions, discussed in the 'Exceptions in repr functions' section, which can be changed by settingcheap_repr.raise_exceptions = Trueor callingraise_exceptions_from_default_repr().cheap_repr.max_level, discussed above.Other miscellaneous functionsbasic_repr(x)returns a string that looks like the defaultobject.__repr__. This is handy if you don't want to write your own repr function to register. Simply register this function instead, e.g.>>>fromcheap_reprimportbasic_repr>>>register_repr(MyClass)(basic_repr)>>>cheap_repr(MyClass([1,2,3,4]))'<MyClass instance at 0x10f39dda0>'normal_repr(x)returnsrepr(x)- register it with a class to indicate that its own__repr__method is already fine. This prevents it from being supressed when its output is a bit long.try_register_repris handy when you want to register a repr function for a class that may not exist, e.g. if the class is in a third party package that may not be installed. See the docstring for more details.