在python中,有时候会出现中英文混合输出的情形,但是由于中文默认是全角格式(一个中文字符占用两个字符宽度),这会对python原生的print
函数带来一些障碍。尤其是用户用print
对齐输出的时候,这种差异会导致文本无法准确对齐。为了解决这种问题,这里提出一种方法。
python的print
函数,在进行对齐处理的时候,首先需要判断字符串的长度。这个就是通常的len()
函数。python在计算字符串长度的时候,任何字符都只会被算作长度1,无论全角还是半角,所以会有下面的情况:
> len("一二三")
3
> len("123")
3
但是对于对于全角字符,打印宽度是两个字节,半角字符是单个字节,譬如下例:
这里很明显的看到,同样的长度为3的字符,全角字符是半角字符一倍的打印长度。
这种差距,会影响到print
的对齐打印,譬如下例:
这个是一个右对齐的示例,print函数首先计算了打印对象的长度len()
,得到了这个打印对象的长度为3(此处忽略全角和半角),所以print
会从右对齐的20节点开始排布,意即print
把从第18 个字符的位置开始打印,这里用红线表示,所以无论全角还是半角对象,print
都会从第18 个字符的位置打印。
按照正常字符(半角),文本会在第20个字符位置完成打印,如上图的蓝线位置,但是由于全角字符的占用了更多的字符,所以这里的全角字符会占用18~23 字符位置,这样会导致打印对齐出现问题:包含全角的字符串会超出限定的界定位置。譬如上述的蓝色位置。超出的数量也很好理解,就是全角字符的个数,意即上述绿线的位置,上述示例包含三个全角字符,就会产出三个字符位置。
以此类推,如果print
在同行继续打印其他字符,字符串里边包含全角字符,那么后续的打印就会一直被前述全角字符的打印结果影响,
这种方式也适用于全半角混合输出,示例如下:
对应的,居中对齐模式也会有类似的影响
了解了上述原理,用户可以根据这种特性,自动完成对于全角半角混合模式的打印对齐处理。思路是:在对齐宽度上对全角字符额外的宽度进行考虑,这样可以构建一个中英文混合模式的打印对齐。代码如下:
def get_number(char):
count = 0
for item in char:
# chinese char and chinese punctuation mark
if 0x4E00 <= ord(item) <= 0x9FA5 or 0xFF00 <= ord(item) <=0xFFEF or 0x3000 <= ord(item) <= 0x303F:
count += 1
return count
def print_hybrid(char, align, length):
if align=='l' or align=='left' :
anchor = '<'
elif align=='c' or align=='center':
anchor = '^'
elif align=='r' or align=='right':
anchor = '>'
else:
ut.print_error('Not support align type. Current support is l(left), c(center), r(right)')
return -1
add_len = get_number(char)
if add_len >= length:
p_len = 0
else:
p_len = length - add_len
return f'{char:{anchor}{p_len}}'
各种混合模式打印示例:
可见,此种方法建立在print
原生的打印机制,辅助计算全角字符的数量的方法,实现的了全半角混合打印的对齐效果。