Каков оптимальный подход для проверки типов объектов аргументов метода в Python? - PullRequest
2 голосов
/ 10 июля 2020

Это не конкретная c проблема с кодом, а скорее открытый концептуальный вопрос, поэтому я надеюсь, что он в нужном месте.

У меня есть pandas фрейм данных, и я часто подмножество данных о граничных временах и других необязательных переменных, здесь частота. Частота имеет дискретные значения, поэтому я могу выбирать данные из одного или нескольких каналов. Имеющаяся у меня функция выглядит примерно так:

def subset_data(data, times, freq=None):

    sub_data = data.loc[data['time'].between(*times), :]

    if freq is not None:
   
        if isinstance(freq, int):

            sub_data = sub_data.loc[sub_data['frequency'] == freq, :]

        elif isinstance(freq, tuple):

            sub_data = sub_data.loc[sub_data['frequency'].between(*freq), :]
                
    return sub_data

Я хотел изменить второе условие, чтобы оно было более общей проверкой для любого типа numeri c, и я нашел этот вопрос - Что такое самый pythoni c способ проверить, является ли объект числом? . Принятый ответ заставил меня усомниться в моем подходе и его обоснованности в целом. Последний пункт, в частности:

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

Я интерпретирую это как подразумевающее, что я должен сделать что-то вроде этого

def subset_data(data, times, freq=None):

    sub_data = data.loc[data['time'].between(*times), :]

    if freq is not None:

        try:
   
            if isinstance(freq, tuple):

                sub_data = sub_data.loc[sub_data['frequency'].between(*freq), :]
       
            elif isinstance(freq, int):

                sub_data = sub_data.loc[sub_data['frequency'] == freq, :]

        except TypeError:

            print('sub_data filtered on time only. freq must be numeric.')

    return sub_data

или

if isinstance(freq, tuple):

    sub_data = sub_data.loc[sub_data['frequency'].between(*freq), :]
       
elif isinstance(freq, int):

    sub_data = sub_data.loc[sub_data['frequency'] == freq, :]

else:

    raise TypeError('freq must be tuple or numeric')

, но мне было бы интересно узнать, если это что-то близкое к консенсус.

В оригинале также отсутствует некоторая проверка на полноту - я слишком ленив, чтобы написать это в собственном коде, и чувствую, что это добавляет ненужного беспорядка, если я предполагаю, что я буду единственным, кто его использует и иметь априорное знание типов. Если бы это было не так, я бы включил:

if isinstance(freq, int):

    sub_data = sub_data.loc[sub_data['frequency'] == freq, :]

elif isinstance(freq, tuple) and len(freq) == 2:

    if isinstance(freq[0], int) and isinstance(freq[1], int):

        sub_data = sub_data.loc[sub_data['frequency'].between(*freq), :]

Является ли практика явной проверки типа и атрибутов объекта, и этот подход к проверке в целом, уместен в Python, или мой где-то не хватает знаний? Может, все можно было бы написать короче, а мне чего-то не хватает. Технически в этом посте есть два вопроса, но я надеюсь, что общая, всеобъемлющая концепция достаточно ясна, чтобы быть полезной для других и позволить получить некоторые ответы.

1 Ответ

1 голос
/ 10 июля 2020

Если я не ошибаюсь, при втором подходе с использованием try / except, если входящий тип неверен, вам будет просто показано TypeError:..., а не точное определение того, что именно вызывает проблему в код. С учетом сказанного, первый подход, вы усиливаете процесс проверки, проверяя два условия int и tuple, что хорошо. У меня не было бы предпочтений, но оба подхода мне подходят, хотя, если бы предложение Exception, вы могли бы сделать его более подробным, чтобы получить конкретный c журнал ошибок (если есть).

Хороший пример понимания Exceptions, если вы хотите, было бы слишком внимательно изучить примеры KeyError при попытке доступа к элементу или значению в словаре, который не существует, а затем print(e) #e is the error from KeyError exception being raised. Надеюсь, это немного поможет. Ура.

...