[Tutor] Formatting objects, was Re: Beginners question

Peter Otten __peter__ at web.de
Sun Apr 5 05:27:07 EDT 2020


DL Neil via Tutor wrote:

> On 5/04/20 1:53 PM, Alex Kleider wrote:
>> 
>> I've been surprised not to have seen, in this thread, any mention made
>> of the following use pattern:
>> 
>> print("{first} {last}, {address}, {city}, {province}, {code},
>> {country}".format(**record))
>> 
>> Is this possible with any of the other (is it three) formatting methods?
>> It's a pattern I've come to appreciate very very much.
> 
> 
> +1
> 
> Possibly not as popular as deserved because it tastes of commercial
> application, and thus falls outside the ambit of scientists, data
> scientists, ML/AI engineers, liars, damned liars, statisticians...
> 
> I dislike using relative positioning for anything (it slows
> reading/comprehension) - which condemns older string-formatting methods
> (in my eyes).
> 
> If the mix of data-values and string-constants reaches a certain point,
> instead of throwing the usual tuple of data at print(), I find f-strings
> coming into play.
> 
> Contrarily, when working with classes/objects I rapidly grew sick of
> writing self. or instanceNM. in front of every attribute to be printed!
> 
> That in-turn became a recommendation for classes to include an as_dict()
> method (or two), eg
> 
> class Person():
> def __init__( self, first, last, ...):
> ...
> @property
> def address_as_dict( self ):
> return ...
> 
> then the above print() becomes:
> 
> print( "{first} {last}, {address}, {city}, {province}, {code},
> {country}".format( instance.address_as_dict ) )
> 
> (even easier if that combination of fields is already a data-structure
> within the class)

An as_dict property (or method, to indicate it's not a lightweight 
operation) may often be useful, but if you are only requiring it for string 
formatting I'd rather write a helper function that can handle arbitrary 
objects:

$ cat tmp.py
class AsDictAdapter:
    def __init__(self, obj):
        self.obj = obj

    def __getitem__(self, name):
        try:
            return getattr(self.obj, name)
        except AttributeError:
            raise KeyError(name)


def format_object(template, obj):
    return template.format_map(AsDictAdapter(obj))


class Person:
    def __init__(self, first, last, profession):
        self.first = first
        self.last = last
        self.profession = profession


person = Person("Jim", "Knopf", "Lokomotivführer")
print(format_object("{last}, {first}: {profession}", person))
$ python3 tmp.py
Knopf, Jim: Lokomotivführer
$



More information about the Tutor mailing list