当我们记得自己插入空间时,我们如何防止Python自动插入空间字符



假装" ."是一个空间字符。然后,Python的打印功能的行为如下:

   print("ham is", 5)    "ham.is.5"
   print("ham is ", 5)   "ham.is..5"

Python的print功能总是在相邻对象之间插入空格。

我们试图编写具有以下行为的函数sprint

   sprint("ham is", 5)    "ham.is.5"
   sprint("ham is ", 5)   "ham.is.5"

给定 sprint(left, right),我们仅在 leftright之间插入一个空间,而 left以白色空间char或 right结束,以白色空间char开始。

  • sprint需要接受任何数量的参数,就像print一样。
  • sprint是关键字参数end所需的,就像print一样。
  • sprint应该尽可能像print,除了何时插入空间的决定。

以下代码执行技巧

import itertools as itts
import sys
def sprint(*args, **kwargs):
    """
   If you do *not* insert the space between strings, then sprint will insert one for you
        if you *do* insert the space, then sprint won't insert a space
    sprint("ham is", 5)    "ham.is.5"
    sprint("ham is ", 5)   "ham.is.5"
    sprint mostly behaves like print.
    However, unlike ....
        print("", end = "")
    we have ...
        sprint("", end = "")
    ... will cause an error
    """
    try:
        # suppose someone input a keyword argument for `end`
        # We wish to append that string to the end of `args`
        # if `end == "t"`, then the new argument list will have
        # a tab character as the very last argument 
        args = itts.chain(args, itts.repeat(kwargs["end"], 1))
    except KeyError:
        # in this case, no keyword argument `end` was used
        # we append nothing to the end of `args`
        pass
    # convert everything into a string
    sargs = (str(x) for x in args)
    # sargs = filter out empty strings(sargs)
    sargs = filter(lambda x: x != "", sargs)
    try:
        while True:
            got_left = False
            left = next(sargs)
            got_left = True
            right = next(sargs)
            sprint_two(left, right)
    except StopIteration:
        if got_left:
            # if an odd number of arguments were received
            sprint_one(left)
    return None
def sprint_two(left, right):
    """
    print exactly two items, no more, and no less.
    """
    # assert (left and right are strings)
    assert(isinstance(left, str) and isinstance(right, str))
    # if (left ends in white space) or (right begins with white space)
    whitey = " fnrtv"
    if (left[-1] in whitey) or (right[-1] in whitey):
        # print (left, right) without space char inserted in-between
        r = sprint_one(left, right)
    else:
        r = sprint_one(left, " ", right)
    return r
def sprint_one(*args):
    """
    PRECONDITION: all input arguments must be strings
    mainly wrote this function so that didn't have to repeatedly
    `sys.stdout.write(''.join(args))`, which looks very ugly 
    """
    sys.stdout.write(''.join(args))  

相关内容

最新更新