如何为 Python 输出的账单左右两侧添加星号边框?
技术老齐
可以用一个函数统一补齐行宽,并在左右两侧添加星号。账单的每一行都由这个函数输出,顶部和底部仍用 "*" * 50,这样就能围出完整的边框。
为什么只加星号还不够?
直接写 print("*" + text + "*"),右侧星号的位置会随文字长度变化。要让右边框对齐,需要先用空格把每行补到相同宽度。
原代码中的 \t 也不适合精确排版。制表符会跳到下一个制表位,显示宽度取决于当前位置,因此这里用字符串格式化控制列宽。
如果账单总宽度为 50,每行的结构是:
* + 空格 + 正文 + 空格 + *
正文可用宽度就是 50 - 4 = 46。
用统一的函数输出账单
先定义总宽度和正文宽度,再用 print_line() 输出正文、分隔线和空行:
p1_name, p1_price = "Books", 49.95
p2_name, p2_price = "Computer", 579.99
p3_name, p3_price = "Monitor", 124.89
company_name = "coding temple, inc."
company_address = "283 Franklin St."
company_city = "Boston, MA"
message = "Thanks for shopping with us today!"
WIDTH = 50
CONTENT_WIDTH = WIDTH - 4
PRICE_WIDTH = 16
NAME_WIDTH = CONTENT_WIDTH - PRICE_WIDTH
def print_line(text="", align="<"):
print(f"* {text:{align}{CONTENT_WIDTH}} *")
def print_separator():
print_line("=" * CONTENT_WIDTH)
# Top border
print("*" * WIDTH)
# Company information
print_line(company_name.title(), "^")
print_line(company_address, "^")
print_line(company_city, "^")
print_separator()
# Product table
print_line(
f"{'Product Name':<{NAME_WIDTH}}"
f"{'Product Price':>{PRICE_WIDTH}}"
)
products = [
(p1_name, p1_price),
(p2_name, p2_price),
(p3_name, p3_price),
]
for name, price in products:
price_text = f"${price:.2f}"
print_line(
f"{name.title():<{NAME_WIDTH}}"
f"{price_text:>{PRICE_WIDTH}}"
)
print_separator()
# Total
total = sum(price for _, price in products)
print_line("Total", ">")
print_line(f"${total:.2f}", ">")
print_separator()
# Empty lines also need side borders
print_line()
print_line(message, "^")
print_line()
# Bottom border
print("*" * WIDTH)
print_line() 用这一行完成填充和边框输出:
print(f"* {text:{align}{CONTENT_WIDTH}} *")
CONTENT_WIDTH 指定正文的最小宽度,不足的部分默认用空格填充。align 控制对齐方式:
<:左对齐,也是函数的默认值。^:居中,用于公司信息和感谢语。>:右对齐,用于合计部分。
商品名称和价格各有固定的列宽,可以去掉原来用于对齐的所有 \t。价格使用 .2f,统一显示两位小数。
使用时注意
格式化指定的是最小宽度,超长文字不会自动截断。如果商品名称或感谢语超过预留空间,右侧边框仍会向右偏移。这时需要增加 WIDTH,或先将长文字换行,再逐行调用 print_line()。
空行也要用 print_line() 输出。直接调用 print(),或在文字中嵌入 \n,都会让相应的行缺少左右边框。
这套写法适用于示例中的英文内容,查看时应使用等宽字体。中文、表情等字符在终端中的显示宽度可能与字符串长度不同,包含这些字符时,需要另按显示列宽计算填充。
备注:内容仅供参考。
