У меня есть класс контейнера, который содержит данные. Когда контейнер создается, существуют разные методы передачи данных.
- Передайте файл, содержащий данные
- Передача данных напрямую через аргументы
- Не передавать данные; просто создайте пустой контейнер
В Java я бы создал три конструктора. Вот как это выглядело бы, если бы это было возможно в Python:
class Container:
def __init__(self):
self.timestamp = 0
self.data = []
self.metadata = {}
def __init__(self, file):
f = file.open()
self.timestamp = f.get_timestamp()
self.data = f.get_data()
self.metadata = f.get_metadata()
def __init__(self, timestamp, data, metadata):
self.timestamp = timestamp
self.data = data
self.metadata = metadata
В Python я вижу три очевидных решения, но ни один из них не симпатичен:
A: использование аргументов ключевого слова:
def __init__(self, **kwargs):
if 'file' in kwargs:
...
elif 'timestamp' in kwargs and 'data' in kwargs and 'metadata' in kwargs:
...
else:
... create empty container
B: использование аргументов по умолчанию:
def __init__(self, file=None, timestamp=None, data=None, metadata=None):
if file:
...
elif timestamp and data and metadata:
...
else:
... create empty container
C: предоставлять конструктор только для создания пустых контейнеров. Предоставьте методы заполнения контейнеров данными из разных источников.
def __init__(self):
self.timestamp = 0
self.data = []
self.metadata = {}
def add_data_from_file(file):
...
def add_data(timestamp, data, metadata):
...
Решения A и B в основном одинаковы. Мне не нравится делать if/else, тем более, что я должен проверить, были ли предоставлены все аргументы, необходимые для этого метода. A является немного более гибким, чем B, если код когда-либо будет расширен четвертым методом для добавления данных.
Решение C кажется самым приятным, но пользователь должен знать, какой метод он требует. Например: он не может сделать c = Container(args)
, если он не знает, что такое args
.
Каково самое питоническое решение?