reSTify PEP 3101 (#328)
This commit is contained in:
parent
a5e937ea43
commit
cc56b43dcb
185
pep-3101.txt
185
pep-3101.txt
|
@ -5,13 +5,14 @@ Last-Modified: $Date$
|
||||||
Author: Talin <viridia@gmail.com>
|
Author: Talin <viridia@gmail.com>
|
||||||
Status: Final
|
Status: Final
|
||||||
Type: Standards Track
|
Type: Standards Track
|
||||||
Content-Type: text/plain
|
Content-Type: text/x-rst
|
||||||
Created: 16-Apr-2006
|
Created: 16-Apr-2006
|
||||||
Python-Version: 3.0
|
Python-Version: 3.0
|
||||||
Post-History: 28-Apr-2006, 6-May-2006, 10-Jun-2007, 14-Aug-2007, 14-Sep-2008
|
Post-History: 28-Apr-2006, 6-May-2006, 10-Jun-2007, 14-Aug-2007, 14-Sep-2008
|
||||||
|
|
||||||
|
|
||||||
Abstract
|
Abstract
|
||||||
|
========
|
||||||
|
|
||||||
This PEP proposes a new system for built-in string formatting
|
This PEP proposes a new system for built-in string formatting
|
||||||
operations, intended as a replacement for the existing '%' string
|
operations, intended as a replacement for the existing '%' string
|
||||||
|
@ -19,12 +20,13 @@ Abstract
|
||||||
|
|
||||||
|
|
||||||
Rationale
|
Rationale
|
||||||
|
=========
|
||||||
|
|
||||||
Python currently provides two methods of string interpolation:
|
Python currently provides two methods of string interpolation:
|
||||||
|
|
||||||
- The '%' operator for strings. [1]
|
- The '%' operator for strings. [1]_
|
||||||
|
|
||||||
- The string.Template module. [2]
|
- The string.Template module. [2]_
|
||||||
|
|
||||||
The primary scope of this PEP concerns proposals for built-in
|
The primary scope of this PEP concerns proposals for built-in
|
||||||
string formatting operations (in other words, methods of the
|
string formatting operations (in other words, methods of the
|
||||||
|
@ -36,7 +38,7 @@ Rationale
|
||||||
leaving all other variables to be squeezed into the remaining
|
leaving all other variables to be squeezed into the remaining
|
||||||
argument. The current practice is to use either a dictionary or a
|
argument. The current practice is to use either a dictionary or a
|
||||||
tuple as the second argument, but as many people have commented
|
tuple as the second argument, but as many people have commented
|
||||||
[3], this lacks flexibility. The "all or nothing" approach
|
[3]_, this lacks flexibility. The "all or nothing" approach
|
||||||
(meaning that one must choose between only positional arguments,
|
(meaning that one must choose between only positional arguments,
|
||||||
or only named arguments) is felt to be overly constraining.
|
or only named arguments) is felt to be overly constraining.
|
||||||
|
|
||||||
|
@ -53,6 +55,7 @@ Rationale
|
||||||
|
|
||||||
|
|
||||||
Specification
|
Specification
|
||||||
|
=============
|
||||||
|
|
||||||
The specification will consist of the following parts:
|
The specification will consist of the following parts:
|
||||||
|
|
||||||
|
@ -92,10 +95,11 @@ Specification
|
||||||
|
|
||||||
|
|
||||||
String Methods
|
String Methods
|
||||||
|
--------------
|
||||||
|
|
||||||
The built-in string class (and also the unicode class in 2.6) will
|
The built-in string class (and also the unicode class in 2.6) will
|
||||||
gain a new method, 'format', which takes an arbitrary number of
|
gain a new method, 'format', which takes an arbitrary number of
|
||||||
positional and keyword arguments:
|
positional and keyword arguments::
|
||||||
|
|
||||||
"The story of {0}, {1}, and {c}".format(a, b, c=d)
|
"The story of {0}, {1}, and {c}".format(a, b, c=d)
|
||||||
|
|
||||||
|
@ -106,7 +110,7 @@ String Methods
|
||||||
used to refer to the third argument.
|
used to refer to the third argument.
|
||||||
|
|
||||||
There is also a global built-in function, 'format' which formats
|
There is also a global built-in function, 'format' which formats
|
||||||
a single value:
|
a single value::
|
||||||
|
|
||||||
print(format(10.0, "7.3g"))
|
print(format(10.0, "7.3g"))
|
||||||
|
|
||||||
|
@ -114,6 +118,7 @@ String Methods
|
||||||
|
|
||||||
|
|
||||||
Format Strings
|
Format Strings
|
||||||
|
--------------
|
||||||
|
|
||||||
Format strings consist of intermingled character data and markup.
|
Format strings consist of intermingled character data and markup.
|
||||||
|
|
||||||
|
@ -124,19 +129,19 @@ Format Strings
|
||||||
what should be placed in the output string in place of the markup.
|
what should be placed in the output string in place of the markup.
|
||||||
|
|
||||||
Brace characters ('curly braces') are used to indicate a
|
Brace characters ('curly braces') are used to indicate a
|
||||||
replacement field within the string:
|
replacement field within the string::
|
||||||
|
|
||||||
"My name is {0}".format('Fred')
|
"My name is {0}".format('Fred')
|
||||||
|
|
||||||
The result of this is the string:
|
The result of this is the string::
|
||||||
|
|
||||||
"My name is Fred"
|
"My name is Fred"
|
||||||
|
|
||||||
Braces can be escaped by doubling:
|
Braces can be escaped by doubling::
|
||||||
|
|
||||||
"My name is {0} :-{{}}".format('Fred')
|
"My name is {0} :-{{}}".format('Fred')
|
||||||
|
|
||||||
Which would produce:
|
Which would produce::
|
||||||
|
|
||||||
"My name is Fred :-{}"
|
"My name is Fred :-{}"
|
||||||
|
|
||||||
|
@ -146,6 +151,7 @@ Format Strings
|
||||||
|
|
||||||
|
|
||||||
Simple and Compound Field Names
|
Simple and Compound Field Names
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
Simple field names are either names or numbers. If numbers, they
|
Simple field names are either names or numbers. If numbers, they
|
||||||
must be valid base-10 integers; if names, they must be valid
|
must be valid base-10 integers; if names, they must be valid
|
||||||
|
@ -153,7 +159,7 @@ Simple and Compound Field Names
|
||||||
argument, while a name is used to identify a keyword argument.
|
argument, while a name is used to identify a keyword argument.
|
||||||
|
|
||||||
A compound field name is a combination of multiple simple field
|
A compound field name is a combination of multiple simple field
|
||||||
names in an expression:
|
names in an expression::
|
||||||
|
|
||||||
"My name is {0.name}".format(open('out.txt', 'w'))
|
"My name is {0.name}".format(open('out.txt', 'w'))
|
||||||
|
|
||||||
|
@ -168,7 +174,7 @@ Simple and Compound Field Names
|
||||||
operator. The reason for allowing these operators is that they don't
|
operator. The reason for allowing these operators is that they don't
|
||||||
normally have side effects in non-pathological code.
|
normally have side effects in non-pathological code.
|
||||||
|
|
||||||
An example of the 'getitem' syntax:
|
An example of the 'getitem' syntax::
|
||||||
|
|
||||||
"My name is {0[name]}".format(dict(name='Fred'))
|
"My name is {0[name]}".format(dict(name='Fred'))
|
||||||
|
|
||||||
|
@ -187,18 +193,19 @@ Simple and Compound Field Names
|
||||||
not required to enforce the rule about a simple or dotted name
|
not required to enforce the rule about a simple or dotted name
|
||||||
being a valid Python identifier. Instead, it will rely on the
|
being a valid Python identifier. Instead, it will rely on the
|
||||||
getattr function of the underlying object to throw an exception if
|
getattr function of the underlying object to throw an exception if
|
||||||
the identifier is not legal. The str.format() function will have
|
the identifier is not legal. The ``str.format()`` function will have
|
||||||
a minimalist parser which only attempts to figure out when it is
|
a minimalist parser which only attempts to figure out when it is
|
||||||
"done" with an identifier (by finding a '.' or a ']', or '}',
|
"done" with an identifier (by finding a '.' or a ']', or '}',
|
||||||
etc.).
|
etc.).
|
||||||
|
|
||||||
|
|
||||||
Format Specifiers
|
Format Specifiers
|
||||||
|
-----------------
|
||||||
|
|
||||||
Each field can also specify an optional set of 'format
|
Each field can also specify an optional set of 'format
|
||||||
specifiers' which can be used to adjust the format of that field.
|
specifiers' which can be used to adjust the format of that field.
|
||||||
Format specifiers follow the field name, with a colon (':')
|
Format specifiers follow the field name, with a colon (':')
|
||||||
character separating the two:
|
character separating the two::
|
||||||
|
|
||||||
"My name is {0:8}".format('Fred')
|
"My name is {0:8}".format('Fred')
|
||||||
|
|
||||||
|
@ -209,7 +216,7 @@ Format Specifiers
|
||||||
|
|
||||||
Format specifiers can themselves contain replacement fields.
|
Format specifiers can themselves contain replacement fields.
|
||||||
For example, a field whose field width is itself a parameter
|
For example, a field whose field width is itself a parameter
|
||||||
could be specified via:
|
could be specified via::
|
||||||
|
|
||||||
"{0:{1}}".format(a, b)
|
"{0:{1}}".format(a, b)
|
||||||
|
|
||||||
|
@ -221,30 +228,31 @@ Format Specifiers
|
||||||
Note that the doubled '}' at the end, which would normally be
|
Note that the doubled '}' at the end, which would normally be
|
||||||
escaped, is not escaped in this case. The reason is because
|
escaped, is not escaped in this case. The reason is because
|
||||||
the '{{' and '}}' syntax for escapes is only applied when used
|
the '{{' and '}}' syntax for escapes is only applied when used
|
||||||
*outside* of a format field. Within a format field, the brace
|
**outside** of a format field. Within a format field, the brace
|
||||||
characters always have their normal meaning.
|
characters always have their normal meaning.
|
||||||
|
|
||||||
The syntax for format specifiers is open-ended, since a class
|
The syntax for format specifiers is open-ended, since a class
|
||||||
can override the standard format specifiers. In such cases,
|
can override the standard format specifiers. In such cases,
|
||||||
the str.format() method merely passes all of the characters between
|
the ``str.format()`` method merely passes all of the characters between
|
||||||
the first colon and the matching brace to the relevant underlying
|
the first colon and the matching brace to the relevant underlying
|
||||||
formatting method.
|
formatting method.
|
||||||
|
|
||||||
|
|
||||||
Standard Format Specifiers
|
Standard Format Specifiers
|
||||||
|
--------------------------
|
||||||
|
|
||||||
If an object does not define its own format specifiers, a standard
|
If an object does not define its own format specifiers, a standard
|
||||||
set of format specifiers is used. These are similar in concept to
|
set of format specifiers is used. These are similar in concept to
|
||||||
the format specifiers used by the existing '%' operator, however
|
the format specifiers used by the existing '%' operator, however
|
||||||
there are also a number of differences.
|
there are also a number of differences.
|
||||||
|
|
||||||
The general form of a standard format specifier is:
|
The general form of a standard format specifier is::
|
||||||
|
|
||||||
[[fill]align][sign][#][0][minimumwidth][.precision][type]
|
[[fill]align][sign][#][0][minimumwidth][.precision][type]
|
||||||
|
|
||||||
The brackets ([]) indicate an optional element.
|
The brackets ([]) indicate an optional element.
|
||||||
|
|
||||||
Then the optional align flag can be one of the following:
|
Then the optional align flag can be one of the following::
|
||||||
|
|
||||||
'<' - Forces the field to be left-aligned within the available
|
'<' - Forces the field to be left-aligned within the available
|
||||||
space (This is the default.)
|
space (This is the default.)
|
||||||
|
@ -266,7 +274,7 @@ Standard Format Specifiers
|
||||||
must be followed by an alignment flag.
|
must be followed by an alignment flag.
|
||||||
|
|
||||||
The 'sign' option is only valid for numeric types, and can be one
|
The 'sign' option is only valid for numeric types, and can be one
|
||||||
of the following:
|
of the following::
|
||||||
|
|
||||||
'+' - indicates that a sign should be used for both
|
'+' - indicates that a sign should be used for both
|
||||||
positive as well as negative numbers
|
positive as well as negative numbers
|
||||||
|
@ -295,7 +303,7 @@ Standard Format Specifiers
|
||||||
|
|
||||||
Finally, the 'type' determines how the data should be presented.
|
Finally, the 'type' determines how the data should be presented.
|
||||||
|
|
||||||
The available integer presentation types are:
|
The available integer presentation types are::
|
||||||
|
|
||||||
'b' - Binary. Outputs the number in base 2.
|
'b' - Binary. Outputs the number in base 2.
|
||||||
'c' - Character. Converts the integer to the corresponding
|
'c' - Character. Converts the integer to the corresponding
|
||||||
|
@ -311,7 +319,7 @@ Standard Format Specifiers
|
||||||
number separator characters.
|
number separator characters.
|
||||||
'' (None) - the same as 'd'
|
'' (None) - the same as 'd'
|
||||||
|
|
||||||
The available floating point presentation types are:
|
The available floating point presentation types are::
|
||||||
|
|
||||||
'e' - Exponent notation. Prints the number in scientific
|
'e' - Exponent notation. Prints the number in scientific
|
||||||
notation using the letter 'e' to indicate the exponent.
|
notation using the letter 'e' to indicate the exponent.
|
||||||
|
@ -337,28 +345,29 @@ Standard Format Specifiers
|
||||||
Objects are able to define their own format specifiers to
|
Objects are able to define their own format specifiers to
|
||||||
replace the standard ones. An example is the 'datetime' class,
|
replace the standard ones. An example is the 'datetime' class,
|
||||||
whose format specifiers might look something like the
|
whose format specifiers might look something like the
|
||||||
arguments to the strftime() function:
|
arguments to the ``strftime()`` function::
|
||||||
|
|
||||||
"Today is: {0:%a %b %d %H:%M:%S %Y}".format(datetime.now())
|
"Today is: {0:%a %b %d %H:%M:%S %Y}".format(datetime.now())
|
||||||
|
|
||||||
For all built-in types, an empty format specification will produce
|
For all built-in types, an empty format specification will produce
|
||||||
the equivalent of str(value). It is recommended that objects
|
the equivalent of ``str(value)``. It is recommended that objects
|
||||||
defining their own format specifiers follow this convention as
|
defining their own format specifiers follow this convention as
|
||||||
well.
|
well.
|
||||||
|
|
||||||
|
|
||||||
Explicit Conversion Flag
|
Explicit Conversion Flag
|
||||||
|
------------------------
|
||||||
|
|
||||||
The explicit conversion flag is used to transform the format field value
|
The explicit conversion flag is used to transform the format field value
|
||||||
before it is formatted. This can be used to override the type-specific
|
before it is formatted. This can be used to override the type-specific
|
||||||
formatting behavior, and format the value as if it were a more
|
formatting behavior, and format the value as if it were a more
|
||||||
generic type. Currently, two explicit conversion flags are
|
generic type. Currently, two explicit conversion flags are
|
||||||
recognized:
|
recognized::
|
||||||
|
|
||||||
!r - convert the value to a string using repr().
|
!r - convert the value to a string using repr().
|
||||||
!s - convert the value to a string using str().
|
!s - convert the value to a string using str().
|
||||||
|
|
||||||
These flags are placed before the format specifier:
|
These flags are placed before the format specifier::
|
||||||
|
|
||||||
"{0!r:20}".format("Hello")
|
"{0!r:20}".format("Hello")
|
||||||
|
|
||||||
|
@ -371,15 +380,16 @@ Explicit Conversion Flag
|
||||||
|
|
||||||
|
|
||||||
Controlling Formatting on a Per-Type Basis
|
Controlling Formatting on a Per-Type Basis
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
Each Python type can control formatting of its instances by defining
|
Each Python type can control formatting of its instances by defining
|
||||||
a __format__ method. The __format__ method is responsible for
|
a ``__format__`` method. The ``__format__`` method is responsible for
|
||||||
interpreting the format specifier, formatting the value, and
|
interpreting the format specifier, formatting the value, and
|
||||||
returning the resulting string.
|
returning the resulting string.
|
||||||
|
|
||||||
The new, global built-in function 'format' simply calls this special
|
The new, global built-in function 'format' simply calls this special
|
||||||
method, similar to how len() and str() simply call their respective
|
method, similar to how ``len()`` and ``str()`` simply call their respective
|
||||||
special methods:
|
special methods::
|
||||||
|
|
||||||
def format(value, format_spec):
|
def format(value, format_spec):
|
||||||
return value.__format__(format_spec)
|
return value.__format__(format_spec)
|
||||||
|
@ -388,24 +398,24 @@ Controlling Formatting on a Per-Type Basis
|
||||||
"None" value in Python is an object and can have methods.)
|
"None" value in Python is an object and can have methods.)
|
||||||
|
|
||||||
Several built-in types, including 'str', 'int', 'float', and 'object'
|
Several built-in types, including 'str', 'int', 'float', and 'object'
|
||||||
define __format__ methods. This means that if you derive from any of
|
define ``__format__`` methods. This means that if you derive from any of
|
||||||
those types, your class will know how to format itself.
|
those types, your class will know how to format itself.
|
||||||
|
|
||||||
The object.__format__ method is the simplest: It simply converts the
|
The ``object.__format__`` method is the simplest: It simply converts the
|
||||||
object to a string, and then calls format again:
|
object to a string, and then calls format again::
|
||||||
|
|
||||||
class object:
|
class object:
|
||||||
def __format__(self, format_spec):
|
def __format__(self, format_spec):
|
||||||
return format(str(self), format_spec)
|
return format(str(self), format_spec)
|
||||||
|
|
||||||
The __format__ methods for 'int' and 'float' will do numeric formatting
|
The ``__format__`` methods for 'int' and 'float' will do numeric formatting
|
||||||
based on the format specifier. In some cases, these formatting
|
based on the format specifier. In some cases, these formatting
|
||||||
operations may be delegated to other types. So for example, in the case
|
operations may be delegated to other types. So for example, in the case
|
||||||
where the 'int' formatter sees a format type of 'f' (meaning 'float')
|
where the 'int' formatter sees a format type of 'f' (meaning 'float')
|
||||||
it can simply cast the value to a float and call format() again.
|
it can simply cast the value to a float and call ``format()`` again.
|
||||||
|
|
||||||
Any class can override the __format__ method to provide custom
|
Any class can override the ``__format__`` method to provide custom
|
||||||
formatting for that type:
|
formatting for that type::
|
||||||
|
|
||||||
class AST:
|
class AST:
|
||||||
def __format__(self, format_spec):
|
def __format__(self, format_spec):
|
||||||
|
@ -413,17 +423,18 @@ Controlling Formatting on a Per-Type Basis
|
||||||
|
|
||||||
Note for Python 2.x: The 'format_spec' argument will be either
|
Note for Python 2.x: The 'format_spec' argument will be either
|
||||||
a string object or a unicode object, depending on the type of the
|
a string object or a unicode object, depending on the type of the
|
||||||
original format string. The __format__ method should test the type
|
original format string. The ``__format__`` method should test the type
|
||||||
of the specifiers parameter to determine whether to return a string or
|
of the specifiers parameter to determine whether to return a string or
|
||||||
unicode object. It is the responsibility of the __format__ method
|
unicode object. It is the responsibility of the ``__format__`` method
|
||||||
to return an object of the proper type.
|
to return an object of the proper type.
|
||||||
|
|
||||||
Note that the 'explicit conversion' flag mentioned above is not passed
|
Note that the 'explicit conversion' flag mentioned above is not passed
|
||||||
to the __format__ method. Rather, it is expected that the conversion
|
to the ``__format__`` method. Rather, it is expected that the conversion
|
||||||
specified by the flag will be performed before calling __format__.
|
specified by the flag will be performed before calling ``__format__``.
|
||||||
|
|
||||||
|
|
||||||
User-Defined Formatting
|
User-Defined Formatting
|
||||||
|
-----------------------
|
||||||
|
|
||||||
There will be times when customizing the formatting of fields
|
There will be times when customizing the formatting of fields
|
||||||
on a per-type basis is not enough. An example might be a
|
on a per-type basis is not enough. An example might be a
|
||||||
|
@ -439,27 +450,28 @@ User-Defined Formatting
|
||||||
customized formatting behavior.
|
customized formatting behavior.
|
||||||
|
|
||||||
The PEP does not attempt to exactly specify all methods and
|
The PEP does not attempt to exactly specify all methods and
|
||||||
properties defined by the Formatter class; instead, those will be
|
properties defined by the ``Formatter`` class; instead, those will be
|
||||||
defined and documented in the initial implementation. However, this
|
defined and documented in the initial implementation. However, this
|
||||||
PEP will specify the general requirements for the Formatter class,
|
PEP will specify the general requirements for the ``Formatter`` class,
|
||||||
which are listed below.
|
which are listed below.
|
||||||
|
|
||||||
Although string.format() does not directly use the Formatter class
|
Although ``string.format()`` does not directly use the ``Formatter`` class
|
||||||
to do formatting, both use the same underlying implementation. The
|
to do formatting, both use the same underlying implementation. The
|
||||||
reason that string.format() does not use the Formatter class directly
|
reason that ``string.format()`` does not use the ``Formatter`` class directly
|
||||||
is because "string" is a built-in type, which means that all of its
|
is because "string" is a built-in type, which means that all of its
|
||||||
methods must be implemented in C, whereas Formatter is a Python
|
methods must be implemented in C, whereas ``Formatter`` is a Python
|
||||||
class. Formatter provides an extensible wrapper around the same
|
class. ``Formatter`` provides an extensible wrapper around the same
|
||||||
C functions as are used by string.format().
|
C functions as are used by ``string.format()``.
|
||||||
|
|
||||||
|
|
||||||
Formatter Methods
|
Formatter Methods
|
||||||
|
-----------------
|
||||||
|
|
||||||
The Formatter class takes no initialization arguments:
|
The ``Formatter`` class takes no initialization arguments::
|
||||||
|
|
||||||
fmt = Formatter()
|
fmt = Formatter()
|
||||||
|
|
||||||
The public API methods of class Formatter are as follows:
|
The public API methods of class ``Formatter`` are as follows::
|
||||||
|
|
||||||
-- format(format_string, *args, **kwargs)
|
-- format(format_string, *args, **kwargs)
|
||||||
-- vformat(format_string, args, kwargs)
|
-- vformat(format_string, args, kwargs)
|
||||||
|
@ -471,13 +483,13 @@ Formatter Methods
|
||||||
'vformat' is the function that does the actual work of formatting. It
|
'vformat' is the function that does the actual work of formatting. It
|
||||||
is exposed as a separate function for cases where you want to pass in
|
is exposed as a separate function for cases where you want to pass in
|
||||||
a predefined dictionary of arguments, rather than unpacking and
|
a predefined dictionary of arguments, rather than unpacking and
|
||||||
repacking the dictionary as individual arguments using the '*args' and
|
repacking the dictionary as individual arguments using the ``*args`` and
|
||||||
'**kwds' syntax. 'vformat' does the work of breaking up the format
|
``**kwds`` syntax. 'vformat' does the work of breaking up the format
|
||||||
template string into character data and replacement fields. It calls
|
template string into character data and replacement fields. It calls
|
||||||
the 'get_positional' and 'get_index' methods as appropriate (described
|
the 'get_positional' and 'get_index' methods as appropriate (described
|
||||||
below.)
|
below.)
|
||||||
|
|
||||||
Formatter defines the following overridable methods:
|
``Formatter`` defines the following overridable methods::
|
||||||
|
|
||||||
-- get_value(key, args, kwargs)
|
-- get_value(key, args, kwargs)
|
||||||
-- check_unused_args(used_args, args, kwargs)
|
-- check_unused_args(used_args, args, kwargs)
|
||||||
|
@ -502,7 +514,7 @@ Formatter Methods
|
||||||
function.
|
function.
|
||||||
|
|
||||||
If the index or keyword refers to an item that does not exist, then an
|
If the index or keyword refers to an item that does not exist, then an
|
||||||
IndexError/KeyError should be raised.
|
``IndexError/KeyError`` should be raised.
|
||||||
|
|
||||||
'check_unused_args' is used to implement checking for unused arguments
|
'check_unused_args' is used to implement checking for unused arguments
|
||||||
if desired. The arguments to this function is the set of all argument
|
if desired. The arguments to this function is the set of all argument
|
||||||
|
@ -517,7 +529,7 @@ Formatter Methods
|
||||||
|
|
||||||
To get a better understanding of how these functions relate to each
|
To get a better understanding of how these functions relate to each
|
||||||
other, here is pseudocode that explains the general operation of
|
other, here is pseudocode that explains the general operation of
|
||||||
vformat.
|
vformat::
|
||||||
|
|
||||||
def vformat(format_string, args, kwargs):
|
def vformat(format_string, args, kwargs):
|
||||||
|
|
||||||
|
@ -574,6 +586,7 @@ Formatter Methods
|
||||||
|
|
||||||
|
|
||||||
Customizing Formatters
|
Customizing Formatters
|
||||||
|
----------------------
|
||||||
|
|
||||||
This section describes some typical ways that Formatter objects
|
This section describes some typical ways that Formatter objects
|
||||||
can be customized.
|
can be customized.
|
||||||
|
@ -582,9 +595,9 @@ Customizing Formatters
|
||||||
can be overridden to alter the way format strings are parsed.
|
can be overridden to alter the way format strings are parsed.
|
||||||
|
|
||||||
One common desire is to support a 'default' namespace, so that
|
One common desire is to support a 'default' namespace, so that
|
||||||
you don't need to pass in keyword arguments to the format()
|
you don't need to pass in keyword arguments to the ``format()``
|
||||||
method, but can instead use values in a pre-existing namespace.
|
method, but can instead use values in a pre-existing namespace.
|
||||||
This can easily be done by overriding get_value() as follows:
|
This can easily be done by overriding ``get_value()`` as follows::
|
||||||
|
|
||||||
class NamespaceFormatter(Formatter):
|
class NamespaceFormatter(Formatter):
|
||||||
def __init__(self, namespace={}):
|
def __init__(self, namespace={}):
|
||||||
|
@ -602,14 +615,14 @@ Customizing Formatters
|
||||||
Formatter.get_value(key, args, kwds)
|
Formatter.get_value(key, args, kwds)
|
||||||
|
|
||||||
One can use this to easily create a formatting function that allows
|
One can use this to easily create a formatting function that allows
|
||||||
access to global variables, for example:
|
access to global variables, for example::
|
||||||
|
|
||||||
fmt = NamespaceFormatter(globals())
|
fmt = NamespaceFormatter(globals())
|
||||||
|
|
||||||
greeting = "hello"
|
greeting = "hello"
|
||||||
print(fmt.format("{greeting}, world!"))
|
print(fmt.format("{greeting}, world!"))
|
||||||
|
|
||||||
A similar technique can be done with the locals() dictionary to
|
A similar technique can be done with the ``locals()`` dictionary to
|
||||||
gain access to the locals dictionary.
|
gain access to the locals dictionary.
|
||||||
|
|
||||||
It would also be possible to create a 'smart' namespace formatter
|
It would also be possible to create a 'smart' namespace formatter
|
||||||
|
@ -621,12 +634,13 @@ Customizing Formatters
|
||||||
|
|
||||||
Another type of customization is to change the way that built-in
|
Another type of customization is to change the way that built-in
|
||||||
types are formatted by overriding the 'format_field' method. (For
|
types are formatted by overriding the 'format_field' method. (For
|
||||||
non-built-in types, you can simply define a __format__ special
|
non-built-in types, you can simply define a ``__format__`` special
|
||||||
method on that type.) So for example, you could override the
|
method on that type.) So for example, you could override the
|
||||||
formatting of numbers to output scientific notation when needed.
|
formatting of numbers to output scientific notation when needed.
|
||||||
|
|
||||||
|
|
||||||
Error handling
|
Error handling
|
||||||
|
--------------
|
||||||
|
|
||||||
There are two classes of exceptions which can occur during formatting:
|
There are two classes of exceptions which can occur during formatting:
|
||||||
exceptions generated by the formatter code itself, and exceptions
|
exceptions generated by the formatter code itself, and exceptions
|
||||||
|
@ -635,10 +649,10 @@ Error handling
|
||||||
In general, exceptions generated by the formatter code itself are
|
In general, exceptions generated by the formatter code itself are
|
||||||
of the "ValueError" variety -- there is an error in the actual "value"
|
of the "ValueError" variety -- there is an error in the actual "value"
|
||||||
of the format string. (This is not always true; for example, the
|
of the format string. (This is not always true; for example, the
|
||||||
string.format() function might be passed a non-string as its first
|
``string.format()`` function might be passed a non-string as its first
|
||||||
parameter, which would result in a TypeError.)
|
parameter, which would result in a ``TypeError``.)
|
||||||
|
|
||||||
The text associated with these internally generated ValueError
|
The text associated with these internally generated ``ValueError``
|
||||||
exceptions will indicate the location of the exception inside
|
exceptions will indicate the location of the exception inside
|
||||||
the format string, as well as the nature of the exception.
|
the format string, as well as the nature of the exception.
|
||||||
|
|
||||||
|
@ -646,7 +660,7 @@ Error handling
|
||||||
dummy frame will be added to the traceback stack to help
|
dummy frame will be added to the traceback stack to help
|
||||||
in determining the location in the string where the exception
|
in determining the location in the string where the exception
|
||||||
occurred. The inserted traceback will indicate that the
|
occurred. The inserted traceback will indicate that the
|
||||||
error occurred at:
|
error occurred at::
|
||||||
|
|
||||||
File "<format_string>;", line XX, in column_YY
|
File "<format_string>;", line XX, in column_YY
|
||||||
|
|
||||||
|
@ -655,6 +669,7 @@ Error handling
|
||||||
|
|
||||||
|
|
||||||
Alternate Syntax
|
Alternate Syntax
|
||||||
|
================
|
||||||
|
|
||||||
Naturally, one of the most contentious issues is the syntax of the
|
Naturally, one of the most contentious issues is the syntax of the
|
||||||
format strings, and in particular the markup conventions used to
|
format strings, and in particular the markup conventions used to
|
||||||
|
@ -664,8 +679,8 @@ Alternate Syntax
|
||||||
proposals, I will cover the ones that are most widely used
|
proposals, I will cover the ones that are most widely used
|
||||||
already.
|
already.
|
||||||
|
|
||||||
- Shell variable syntax: $name and $(name) (or in some variants,
|
- Shell variable syntax: ``$name`` and ``$(name)`` (or in some variants,
|
||||||
${name}). This is probably the oldest convention out there, and
|
``${name}``). This is probably the oldest convention out there, and
|
||||||
is used by Perl and many others. When used without the braces,
|
is used by Perl and many others. When used without the braces,
|
||||||
the length of the variable is determined by lexically scanning
|
the length of the variable is determined by lexically scanning
|
||||||
until an invalid character is found.
|
until an invalid character is found.
|
||||||
|
@ -687,18 +702,18 @@ Alternate Syntax
|
||||||
field index, so that fields can be interpolated out of order.
|
field index, so that fields can be interpolated out of order.
|
||||||
|
|
||||||
- Other bracket-only variations. Various MUDs (Multi-User
|
- Other bracket-only variations. Various MUDs (Multi-User
|
||||||
Dungeons) such as MUSH have used brackets (e.g. [name]) to do
|
Dungeons) such as MUSH have used brackets (e.g. ``[name]``) to do
|
||||||
string interpolation. The Microsoft .Net libraries uses braces
|
string interpolation. The Microsoft .Net libraries uses braces
|
||||||
({}), and a syntax which is very similar to the one in this
|
(``{}``), and a syntax which is very similar to the one in this
|
||||||
proposal, although the syntax for format specifiers is quite
|
proposal, although the syntax for format specifiers is quite
|
||||||
different. [4]
|
different. [4]_
|
||||||
|
|
||||||
- Backquoting. This method has the benefit of minimal syntactical
|
- Backquoting. This method has the benefit of minimal syntactical
|
||||||
clutter, however it lacks many of the benefits of a function
|
clutter, however it lacks many of the benefits of a function
|
||||||
call syntax (such as complex expression arguments, custom
|
call syntax (such as complex expression arguments, custom
|
||||||
formatters, etc.).
|
formatters, etc.).
|
||||||
|
|
||||||
- Other variations include Ruby's #{}, PHP's {$name}, and so
|
- Other variations include Ruby's ``#{}``, PHP's ``{$name}``, and so
|
||||||
on.
|
on.
|
||||||
|
|
||||||
Some specific aspects of the syntax warrant additional comments:
|
Some specific aspects of the syntax warrant additional comments:
|
||||||
|
@ -706,10 +721,10 @@ Alternate Syntax
|
||||||
1) Backslash character for escapes. The original version of
|
1) Backslash character for escapes. The original version of
|
||||||
this PEP used backslash rather than doubling to escape a bracket.
|
this PEP used backslash rather than doubling to escape a bracket.
|
||||||
This worked because backslashes in Python string literals that
|
This worked because backslashes in Python string literals that
|
||||||
don't conform to a standard backslash sequence such as '\n'
|
don't conform to a standard backslash sequence such as ``\n``
|
||||||
are left unmodified. However, this caused a certain amount
|
are left unmodified. However, this caused a certain amount
|
||||||
of confusion, and led to potential situations of multiple
|
of confusion, and led to potential situations of multiple
|
||||||
recursive escapes, i.e. '\\\\{' to place a literal backslash
|
recursive escapes, i.e. ``\\\\{`` to place a literal backslash
|
||||||
in front of a bracket.
|
in front of a bracket.
|
||||||
|
|
||||||
2) The use of the colon character (':') as a separator for
|
2) The use of the colon character (':') as a separator for
|
||||||
|
@ -718,6 +733,7 @@ Alternate Syntax
|
||||||
|
|
||||||
|
|
||||||
Alternate Feature Proposals
|
Alternate Feature Proposals
|
||||||
|
===========================
|
||||||
|
|
||||||
Restricting attribute access: An earlier version of the PEP
|
Restricting attribute access: An earlier version of the PEP
|
||||||
restricted the ability to access attributes beginning with a
|
restricted the ability to access attributes beginning with a
|
||||||
|
@ -730,7 +746,7 @@ Alternate Feature Proposals
|
||||||
is in conflict with the needs of another set of developers who
|
is in conflict with the needs of another set of developers who
|
||||||
strongly lobbied for the ability to pass in a large dict as a
|
strongly lobbied for the ability to pass in a large dict as a
|
||||||
single argument (without flattening it into individual keyword
|
single argument (without flattening it into individual keyword
|
||||||
arguments using the **kwargs syntax) and then have the format
|
arguments using the ``**kwargs`` syntax) and then have the format
|
||||||
string refer to dict entries individually.
|
string refer to dict entries individually.
|
||||||
|
|
||||||
There has also been suggestions to expand the set of expressions
|
There has also been suggestions to expand the set of expressions
|
||||||
|
@ -741,15 +757,16 @@ Alternate Feature Proposals
|
||||||
For cases where the format string is being use to do arbitrary
|
For cases where the format string is being use to do arbitrary
|
||||||
formatting in a data-rich environment, it's recommended to use
|
formatting in a data-rich environment, it's recommended to use
|
||||||
a template engine specialized for this purpose, such as
|
a template engine specialized for this purpose, such as
|
||||||
Genshi [5] or Cheetah [6].
|
Genshi [5]_ or Cheetah [6]_.
|
||||||
|
|
||||||
Many other features were considered and rejected because they
|
Many other features were considered and rejected because they
|
||||||
could easily be achieved by subclassing Formatter instead of
|
could easily be achieved by subclassing ``Formatter`` instead of
|
||||||
building the feature into the base implementation. This includes
|
building the feature into the base implementation. This includes
|
||||||
alternate syntax, comments in format strings, and many others.
|
alternate syntax, comments in format strings, and many others.
|
||||||
|
|
||||||
|
|
||||||
Security Considerations
|
Security Considerations
|
||||||
|
=======================
|
||||||
|
|
||||||
Historically, string formatting has been a common source of
|
Historically, string formatting has been a common source of
|
||||||
security holes in web-based applications, particularly if the
|
security holes in web-based applications, particularly if the
|
||||||
|
@ -769,11 +786,12 @@ Security Considerations
|
||||||
culture of Python developers. So for example, attribute access
|
culture of Python developers. So for example, attribute access
|
||||||
is allowed because it would be considered pathological to write
|
is allowed because it would be considered pathological to write
|
||||||
code where the mere access of an attribute has visible side
|
code where the mere access of an attribute has visible side
|
||||||
effects (whether the code has *invisible* side effects - such
|
effects (whether the code has **invisible** side effects - such
|
||||||
as creating a cache entry for faster lookup - is irrelevant.)
|
as creating a cache entry for faster lookup - is irrelevant.)
|
||||||
|
|
||||||
|
|
||||||
Sample Implementation
|
Sample Implementation
|
||||||
|
=====================
|
||||||
|
|
||||||
An implementation of an earlier version of this PEP was created by
|
An implementation of an earlier version of this PEP was created by
|
||||||
Patrick Maupin and Eric V. Smith, and can be found in the pep3101
|
Patrick Maupin and Eric V. Smith, and can be found in the pep3101
|
||||||
|
@ -783,6 +801,7 @@ Sample Implementation
|
||||||
|
|
||||||
|
|
||||||
Backwards Compatibility
|
Backwards Compatibility
|
||||||
|
=======================
|
||||||
|
|
||||||
Backwards compatibility can be maintained by leaving the existing
|
Backwards compatibility can be maintained by leaving the existing
|
||||||
mechanisms in place. The new system does not collide with any of
|
mechanisms in place. The new system does not collide with any of
|
||||||
|
@ -792,31 +811,33 @@ Backwards Compatibility
|
||||||
|
|
||||||
|
|
||||||
References
|
References
|
||||||
|
==========
|
||||||
|
|
||||||
[1] Python Library Reference - String formating operations
|
.. [1] Python Library Reference - String formating operations
|
||||||
http://docs.python.org/library/stdtypes.html#string-formatting-operations
|
http://docs.python.org/library/stdtypes.html#string-formatting-operations
|
||||||
|
|
||||||
[2] Python Library References - Template strings
|
.. [2] Python Library References - Template strings
|
||||||
http://docs.python.org/library/string.html#string.Template
|
http://docs.python.org/library/string.html#string.Template
|
||||||
|
|
||||||
[3] [Python-3000] String formating operations in python 3k
|
.. [3] [Python-3000] String formating operations in python 3k
|
||||||
https://mail.python.org/pipermail/python-3000/2006-April/000285.html
|
https://mail.python.org/pipermail/python-3000/2006-April/000285.html
|
||||||
|
|
||||||
[4] Composite Formatting - [.Net Framework Developer's Guide]
|
.. [4] Composite Formatting - [.Net Framework Developer's Guide]
|
||||||
http://msdn.microsoft.com/library/en-us/cpguide/html/cpconcompositeformatting.asp?frame=true
|
http://msdn.microsoft.com/library/en-us/cpguide/html/cpconcompositeformatting.asp?frame=true
|
||||||
|
|
||||||
[5] Genshi templating engine.
|
.. [5] Genshi templating engine.
|
||||||
http://genshi.edgewall.org/
|
http://genshi.edgewall.org/
|
||||||
|
|
||||||
[5] Cheetah - The Python-Powered Template Engine.
|
.. [6] Cheetah - The Python-Powered Template Engine.
|
||||||
http://www.cheetahtemplate.org/
|
http://www.cheetahtemplate.org/
|
||||||
|
|
||||||
|
|
||||||
Copyright
|
Copyright
|
||||||
|
=========
|
||||||
|
|
||||||
This document has been placed in the public domain.
|
This document has been placed in the public domain.
|
||||||
|
|
||||||
|
..
|
||||||
Local Variables:
|
Local Variables:
|
||||||
mode: indented-text
|
mode: indented-text
|
||||||
indent-tabs-mode: nil
|
indent-tabs-mode: nil
|
||||||
|
|
Loading…
Reference in New Issue