Форматирование числовых значений, которые также могут быть None - PullRequest
0 голосов
/ 01 июля 2018

Я ищу лучший способ обработать необязательное значение None (пропущенное значение) в таком выражении, как это:

logger.info("temp1 = %.1f, temp2 = %.1f, position = %.2f", t1, t2, pos)

для предотвращения:

TypeError: must be real number, not NoneType

Вот что я делаю сейчас:

logger.info(
    "temp1 = %s, temp2 = %s, position = %s",
    "null" if t1 is None else format(t1, '.1f'),
    "null" if t2 is None else format(t2, '.1f'),
    "null" if pos is None else format(pos, '.2f'))
    # any placeholder like "null", "None", "---", or "N/A" is fine

и мне это не нравится. Есть ли способ лучше? Решение этой небольшой проблемы с использованием str.format или f-strings также поможет.

Ответы [ 3 ]

0 голосов
/ 01 июля 2018

Одним из способов было бы написать простую функцию для этого, например ::

def fin(obj): return "null" if obj is None else format(obj, '.1f')

logging.info("temp1 = %s, temp2 = %s, position = %s", fin(t1), fin(t2), fin(pos))
# INFO:root:temp1 = null, temp2 = 0.2, position = 6.8

Или вы можете написать функцию, которая будет принимать и форматировать несколько аргументов:

def fins(*objs):
    return ("null" if obj is None else format(obj, '.1f') for obj in objs)

logging.info("temp1 = %s, temp2 = %s, position = %s", *fins(t1, t2, pos))
# INFO:root:temp1 = null, temp2 = 0.2, position = 6.8

РЕДАКТИРОВАТЬ: Или, с Python 3.6+ f-строк:

def ff(obj, fmt):
    return "null" if obj is None else format(obj, fmt)

logger.info(f"temp1 = {ff(t1, '.1f')}, temp2 = {ff(t2, '.1f')}, position = {ff(pos, '.2f')}")
# temp1 = None, temp2 = 0.2, position = 6.79

или, используя точность, когда obj является float, и str (obj) в противном случае:

def ff(obj, p):
    return format(obj, '.%df' % p) if isinstance(obj, float) else str(obj)

logger.info(f"temp1 = {ff(t1, 1)}, temp2 = {ff(t2, 1)}, position = {ff(pos, 2)}")
# temp1 = None, temp2 = 0.2, position = 6.79

где во всех случаях:

t1, t2, pos = None, 0.234, 6.789

Если вы хотите преобразовать все числа с плавающей точкой, переданные в качестве logging аргументов, таким образом, вы можете создать пользовательский обработчик , но это кажется излишним и склонным к конвертации вещей, которые вы можете не хочу.

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

Я знаю два пути:

for x in [1.23456, None]:
print(
    '1: {}'.format(x is not None and '{:0.4f}'.format(x) or 'None')
)
print(
    '2: {:{x_fmt}}'.format(x, x_fmt=x is not None and '0.4f' or '')
)

Из:

1: 1.2346
2: 1.2346
1: None
2: None
0 голосов
/ 01 июля 2018

Создайте оболочку, которая проверяет себя при вызове __format__.

class AnyOrNone(object):  # The wrapper is not type-specific
    def __init__(self, value):
        self.value = value

    def __format__(self, *args, **kwargs):
        if self.value is None:
            return "None"
        else:
            return self.value.__format__(*args, **kwargs)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...