Передать список или переменное число аргументов в качестве параметров метода - PullRequest
0 голосов
/ 28 октября 2018

Мне было интересно, что лучшее (наиболее питоническое) решение - передать список или переменное число аргументов функции / методу.

Например, мне нужен следующий класс:

class Dataset():
def __init__(self, *args):
    self.data_set = args

и это часть свойства setter:

@data_set.setter
def data_set(self, args):
    data = []
    for item in args:
        if type(item) is list:
            data = [k for k in item]
            break
        data.append(item)
    self._data_set = data

Я искал в Интернете, но не смог найти много по теме.Моя цель здесь состоит в том, чтобы спроектировать конструктор класса так, чтобы он работал со списком в качестве заданного параметра:

ds1 = Набор данных ([4,3,5])

или номер переменной или аргументы:

ds1 = Набор данных (4,3,5)

Итак, какова лучшая реализация, и я на правильном пути?

1 Ответ

0 голосов
/ 28 октября 2018

Вы можете попробовать это,

class Dataset():
    def __init__(self, *args):
        if isinstance(args[0], list) and len(args) == 1:
            print('Received a list')
        else:
            print('Received:', args)

obj = Dataset(1,2,3)
obj = Dataset([1,2,3], 2)
obj = Dataset([1,2,3])

выходы:

Received: (1, 2, 3)                                                       
Received: ([1, 2, 3], 2)                                                  
Received a list 

Редактировать:

Этот код делает то, что вы хотите, простым способом.Ничего более.Есть и другие способы, они не кажутся мне простыми.

Ваш комментарий на самом деле отличный вопрос.

Проблема не в этом коде, а в том, что вы спрашиваете, иЯзык Python.Вы хотите перегрузку метода, а в Python его нет.

Тестирование типов аргументов не является пифоническим, потому что Python - это динамически типизированный язык. Вы можете сделать это, но вы ограничиваете полезность своих функций определенным типом.

Проверка типа аргумента также приводит к типичной цепочке if..elif.

Если вы пишете функции, взгляните на functools.singledispatch декоратор.Это исключает цепочку if..elif из кода.Используя его, вы можете определить базовую функцию и зарегистрировать конкретные реализации для каждого типа.Просто и читабельно.Но это приводит к реализации функции на основе первого аргумента.Теперь, например, методы, это не будет работать из-за self.Вы можете изменить это , но это уже не выглядит просто.

Поскольку Python не поддерживает непосредственную перегрузку методов / функций, то, что вы просили, не является распространенным шаблоном для использования.

Теперь Аран Фей дает вам хороший совет.Подобное поведение при кодировании редко встречается в Python и фактически вносит двусмысленность.Ваш контракт API становится неясным.Должен ли я передать список или varargs.А почему выбор?Просто потому, что у вас уже есть кортежи и диктанты с * args и * kwargs и вы тоже хотите списки?А как насчет построения «varargs» в качестве элементов списка?

Вы запрашиваете список или переменное количество аргументов, но список также содержит «переменное количество аргументов».

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

...