[Python-3000] string.Formatter class
Ron Adam
rrr at ronadam.com
Fri Aug 31 04:21:18 CEST 2007
Eric Smith wrote:
> Ron Adam wrote:
>>
>>
>> Eric Smith wrote:
>>> Ron Adam wrote:
>>>>> get_field(field_name, args, kwargs, used_args)
>>>>> Given a field_name as returned by parse, convert it to an object to
>>>>> be formatted. The default version takes strings of the form
>>>>> defined in the PEP, such as "0[name]" or "label.title". It records
>>>>> which args have been used in used_args. args and kwargs are as
>>>>> passed in to vformat.
>>>>
>>>> Rather than pass the used_args set out and have it modified in a
>>>> different methods, I think it would be better to pass the arg_used
>>>> back along with the object. That keeps all the code that is
>>>> involved in checking used args is in one method. The arg_used value
>>>> may be useful in other ways as well.
>>>>
>>>> obj, arg_used = self.get_field(field_name, args, kwargs)
>>>> used_args.add(arg_used)
>>>
>>> I'm really not wild about either solution, but I suppose yours is
>>> less objectionable than mine. I'll check this change in tonight
>>> (before the deadline).
>>
>> Cool. I looked at other possible ways, but this seemed to be the
>> easiest to live with. The alternative is to use an attributes to pass
>> and hold values, but sense the Formatter class isn't a data class,
>> that doesn't seem appropriate.
>
> I agree that attributes seem like the wrong way to go about it. It also
> makes recursively calling the formatter impossible without saving state.
>
> I'm still planning on making this change tonight.
>
>>> I think you'd have to say:
>>>
>>> if args_used is not None:
>>> used_args.add(args_used)
>>>
>>> as it's possible that the field was not derived from the args or kwargs.
>>
>> How? From what I can see an exception would be raised in the
>> get_value method.
>>
>> When would I ever want to get a None for args_used?
>
> I meant arg_used.
I understood.
> You're right. I was confusing get_field with get_value. (Surely we can
> pick better names!)
Hmm... how about this?
if field_name is not None:
name, sub_names = field_name._formatter_field_name_split()
obj = self.get_value(name, args, kwargs)
obj = self.get_sub_value(obj, sub_names)
obj = self.convert_field(obj, conversion)
used_args.add(name)
# format the object and append to the result
result.append(self.format_field(obj, format_spec))
This doesn't require passing an arg_used value as it's available in vformat.
Get_sub_value replaces get_field.
def get_sub_value(self, sub_value_name, args, kwargs):
# Get sub value of an object.
# (indices or attributes)
for is_attr, i in sub_value_name:
if is_attr:
obj = getattr(obj, i)
else:
obj = obj[i]
return obj
While it moves more into vformat, I think it's clearer what everything does.
Cheers,
Ron
More information about the Python-3000
mailing list