String Formatting in Python

import struct

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

def main():
    # Python offers excellent support for string formatting.
    # Here are some examples of common string formatting tasks.

    # Python uses format specifiers similar to C's printf tradition.
    # This prints an instance of our Point class.
    p = Point(1, 2)
    print(f"struct1: {p}")

    # To include the object's attributes, we can use vars() or __dict__
    print(f"struct2: {vars(p)}")

    # To print a representation that looks like Python code, use repr()
    print(f"struct3: {repr(p)}")

    # To print the type of a value, use type()
    print(f"type: {type(p)}")

    # Formatting booleans is straightforward
    print(f"bool: {True}")

    # There are many options for formatting integers
    # Use :d for standard base-10 formatting
    print(f"int: {123:d}")

    # This prints a binary representation
    print(f"bin: {14:b}")

    # This prints the character corresponding to the given integer
    print(f"char: {chr(33)}")

    # :x provides hex encoding
    print(f"hex: {456:x}")

    # There are also several formatting options for floats
    # For basic decimal formatting use :f
    print(f"float1: {78.9:f}")

    # :e and :E format the float in scientific notation
    print(f"float2: {123400000.0:e}")
    print(f"float3: {123400000.0:E}")

    # For basic string printing, no format specifier is needed
    print(f"str1: {'\"string\"'}")

    # To represent strings as Python would, use repr()
    print(f"str2: {repr('\"string\"')}")

    # To print a hexadecimal representation of a string, use .encode().hex()
    print(f"str3: {'hex this'.encode().hex()}")

    # To print a representation of a pointer, use id()
    print(f"pointer: {id(p)}")

    # When formatting numbers you will often want to control the width
    # and precision of the resulting figure. To specify the width of an
    # integer, use a number before the format specifier
    print(f"width1: |{12:6d}|{345:6d}|")

    # You can also specify the width of printed floats, and restrict
    # the decimal precision at the same time
    print(f"width2: |{1.2:6.2f}|{3.45:6.2f}|")

    # To left-justify, use the < flag
    print(f"width3: |{1.2:<6.2f}|{3.45:<6.2f}|")

    # You may also want to control width when formatting strings
    print(f"width4: |{'foo':>6s}|{'b':>6s}|")

    # To left-justify use the < flag as with numbers
    print(f"width5: |{'foo':<6s}|{'b':<6s}|")

    # f-strings format and return a string directly
    s = f"f-string: a {'string'}"
    print(s)

    # You can format+print to file objects other than
    # sys.stdout using their write method
    import sys
    sys.stderr.write(f"io: an {'error'}\n")

if __name__ == "__main__":
    main()

This Python code demonstrates various string formatting techniques, mirroring the functionality shown in the Go example. Here are some key points:

  1. Python uses f-strings (formatted string literals) for most string formatting tasks, which is similar to Go’s fmt.Printf but with a more concise syntax.

  2. The Point class is defined to mirror the point struct in the Go example.

  3. Python doesn’t have a direct equivalent to Go’s %#v for printing a source code representation, but repr() serves a similar purpose.

  4. Python uses type() instead of %T to get the type of a value.

  5. Binary, character, and hexadecimal representations are achieved using format specifiers within f-strings.

  6. Python’s string formatting allows for controlling width and precision similar to Go.

  7. Python doesn’t have pointers, so we use id() to get a unique identifier for an object, which serves a similar purpose in this context.

  8. The example demonstrates writing to sys.stderr, which is analogous to Go’s os.Stderr.

To run this program, save it as string_formatting.py and use the Python interpreter:

$ python string_formatting.py

This will output the formatted strings, demonstrating various string formatting techniques in Python.