Как мы можем запретить Python автоматически вставлять символы пробела в операторах печати, если мы сами помним вставить пробел? - PullRequest
0 голосов
/ 17 мая 2019

Представьте, что "." - это пробел. Затем функция печати 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) мы вставляем пробел между left и right, только если left оканчивается символом пробела или right начинается символом пробела.

  • sprint требуется для принятия любого количества аргументов, например print.
  • sprint требуется для ключевого аргумента end, как и print.
  • sprint должно быть как можно больше print, за исключением решения о том, когда вставлять пробелы.

1 Ответ

0 голосов
/ 17 мая 2019

Следующий код делает трюк

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 = " \f\n\r\t\v"
    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))  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...