#python #dictionary
Вопрос:
Я намерен определить класс со свойствами, указанными здесь ниже, и мне интересно, каков наилучший подход между тем, чтобы сделать его наследуемым dict
или dict
иметь атрибут has?
Цель занятия
Это класс, подобный dict, экземпляр которого будет отслеживать файлы на диске, т. Е. он управляет сопоставлением между ключом и дескриптором набора данных (это не прямой файл — для полноты, это ParquetFile()
экземпляр из fastparquet
библиотеки). Называя этот класс DataStore()
, мой вопрос затем материализуется в том, какой наилучший подход между:
# Defining the indexer class 1st @dataclass class Indexer: country: str city: str @property def to_path(self): # Method to derive a path from an Indexer instance @classmethod def from_path(cls, path): # Method to derive a new Indexer instance from a path. # Approach 1: dict as attribute class DataStore1: def __init__(self, path:str, indexer: Indexer): # path: path of main directory, containing several parquet datasets # indexer: class used generate a key from path of individual parquet dataset. self.data = self._keys_datasets_from_path(path, indexer) self.basepath = path def _keys_datasets_from_path(self, path:str, indexer: Indexer) -gt; dict() # Stuff with scanfile(path) and so on... # Approach 2: inheriting from dict class DataStore2(dict): def __init__(self, path:str, indexer: Indexer): # path: path of main directory, containing several parquet datasets # indexer: class used generate a key from path of individual parquet dataset. super.__init__(self._keys_datasets_from_path(path, indexer)) self.basepath = path def _keys_datasets_from_path(self, path:str, indexer: Indexer) -gt; dict() # Stuff with scanfile(path) and so on...
Требования
- Имеет определенный атрибут:
basepath
- Примите один тип ключа (в примере выше:
Indexer
).- проверьте тип ключа при добавлении или изменении нового значения, создайте исключение, если оно не указанного типа.
- Итерация по ключам (как стандартная
dict
)for key in my_store:
Синктатический сахар
- При установке значения для ключа поведение отличается в зависимости от типа значения:
- если значение является
ParquetFile()
экземпляром, то используется нормальное поведение dict.my_store[my_new_key] = my_parquet_file_obj
- если значение является кортежем
(dict, DataFrame)
- если ключ новый, то фрейм данных-это данные, используемые для создания
ParquetFile()
экземпляра, а дикт-конфигурация, используемая для записи набора данных.my_store[my_new_key] = (config_for_writing_new_dataset, data_to_write)
- если ключ существует, фрейм данных-это данные для добавления, а дикт-конфигурация, используемая для добавления данных.
my_store[my_existing_key] = (config_for_appending, data_to_append)
- если ключ новый, то фрейм данных-это данные, используемые для создания
- если значение является
Итак, учитывая эти требования, каков был бы наилучший подход? Может быть, вопрос сводится к тому, какой подход является наиболее гибким для достижения заданных требований и целевого синтаксического сахара? Заранее спасибо за любую помощь и советы!
Комментарии:
1. Есть ли у них какие-либо различия в ваших двух подходах? Как я знаю, второй метод делает наследование классов
object lt;- dict lt;- target
вместоobject lt;- target
первого, поэтому я бы предложил использовать первые подходы, не нужно усложнять ситуацию. Или у вас есть особые потребности..2. Спасибо, что попытались помочь! Извините, я не понимаю, что такое » они » в «Есть ли у них какие-либо различия»? Также я не понимаю, что такое «цель» в цепочке, которую вы сравниваете? Цепочка, которую я вижу между 1 и 2: наследование:
dict -gt; DataStore -gt; obj
/ атрибут:DataStore -gt; obj -gt; dict obj
но не уверен, как ее интерпретировать.3. Не делай этого. В итоге вы получите код, который выглядит как обычные операции диктовки, но ведет себя совсем по-другому. Это поле деятельности для любого разработчика , который появится позже (включая вас через 6 месяцев). Используйте пользовательский класс с соответствующими именами методов. Или, если это не ваша сумка, храните вещи в обычном диктанте и манипулируйте ими с помощью обычных функций, которые понимают логику домена.
4. @pierre_j: Вы рассматривали возможность наследования от
collections.abc.MutableMapping
, который предназначен для создания пользовательскихdict
вещей? Это в основном обертываниеdict
случая члена, но вам нужно только определить__getitem__
,__setitem__
,__delitem__
,__iter__
, и__len__
, и ABC предоставляет все остальныеdict
методы для вас.5. @pierre_j: Нет проблем. Просто для ясности вам также необходимо указать a
__init__
(именно там вы можете решить, где вы будете хранить внутреннююdict
информацию ). Это прямо не указано в документах, но вы тоже несете за это ответственность.