Рубрики
Без рубрики

Полностью автоматизированные объекты метаданных с новой библиотекой Dataclass Python 3.7.

Dataclass – это совершенно новая структура данных, которые отображаются в Python 3.7. Эта статья является руководством для создания полностью автоматических (самозачитанных) объектов метаданных с использованием Dataclasses. Помечено с Python, Dataclass, метаданными.

Dataclass – это совершенно новая структура данных, которые отображаются в Python 3.7. Недавно @Btaskaya написать об этом отличной статьей. Если вы еще не прочитали, вы можете прочитать здесь.

Dataclass имеет перспективные функции для создания многоразовых, самоуверенных и автоматических объектов метаданных. До этого я использовал для использования Дикт Формат для создания объектов метаданных, но копирование и вставка одного и того же объекта все время скучно и конфликт с сухим (не повторять себя) правило.

Это было так:

Metadata = {}
Metadata["id"] = id
Metadata["url"] = url

if something:
    Metadata["some_field"] = some_data

Metadata["media"] = {}
Metadata["media"]["id"] = media_id 
...

Я могу использовать NamedTuple или что-то вместо обдумывать Но у них есть некоторые ограничения И у меня на самом деле не было достаточно времени, чтобы реализовать что-то фантастику в первые дни проекта. Когда I Refactor Code я понимаю, что Dataclass более функционален для моих потребностей.

В этой статье я покажу вам, как реализовать полностью автоматизированные объекты метаданных с помощью Dataclasses Step за шагом.

Часть 1: Внедрить поля метаданных, которые не нуждаются в расчете

На этом шаге нет проблем. Это просто стандартная реализация.

from dataclasses import *


@dataclass
class Metadata:
    title: str
    url: str
    created_at: str = None    # Fields may have default value

Часть 2: Добавьте некоторые поля, которые нуждаются в расчете, и давайте вычисляем его автоматически.

Эти поля получит значения только после расчетов. В нашем случае post_id следует равнить случайное число плюс URL.

import random
from dataclasses import *
@dataclass
class Metadata:
    # Normal fields
    title: str
    url: str
    created_at: str = None
    # Calculated fields
    post_id: str = field(init=False)
    def __post_init__(self):
        random_number = random.randint(100000, 999999)
        self.post_id = f"{random_number}_{self.url}"

__post_init__ Функция рассчитает наше поле post_id после инициации.

Давайте назовем это:

>>> Metadata(
...  title="Some Article",
...  url="https://example.com/article.html",
...  created_at="2018-09-23"
... )
Metadata(title='Some Article', url='https://example.com/article.html', created_at='2018-09-23', post_id='696953_https://example.com/article.html')

Попался!

Часть 3: сделать наши руки грязнее; Добавить __Post_init__ только Pseudo полей

Мы можем захотеть построить автономные комплексные структуры. Например, если одно поле аннотировано, Dataclass может построить всю подструктуру для нас. В нашем случае мы используем дополнительные поля автор_names. и author_ids построить Авторы поле как Список обдумывать . Если информация о авторе не предусмотрена для статьи, стоимость Авторы поле должно быть Нет Отказ

import random
from dataclasses import *


@dataclass
class Metadata:
    # Normal fields
    title: str
    url: str
    created_at: str = None
    authors: list = None
    # Calculated fields
    post_id: str = field(init=False)
    # Non-nullable Pseudo fields
    author_names: InitVar[list]
    author_ids: InitVar[list]

    def __post_init__(self, author_names, author_ids): # You have to pass pseudo fields as the parameter.
        random_number = random.randint(100000, 999999)
        self.post_id = f"{random_number}_{self.url}"
        self.authors = []
        for i in range(0, len(author_names)):
            self.authors.append({"id": author_ids[i], "name": author_names[i]})

Давайте назовем это:

>>> Metadata(
...  title="Some Article",
...  url="https://example.com/article.html",
...  created_at="2018-09-23"
... )

TypeError: non-default argument 'author' follows default argument.

Это не сработало:(

Важное примечание: Вы должны группировать по умолчанию и не по умолчанию.

Попробуйте снова:

import random, json
from dataclasses import *


@dataclass
class Metadata:
    # Non-nullable Pseudo fields
    author_names: InitVar[list]
    author_ids: InitVar[list]
    # Normal fields
    title: str
    url: str
    created_at: str = None
    authors: list = None
    # Calculated fields
    post_id: str = field(init=False)

    def __post_init__(self, author_names, author_ids): # You have to pass pseudo fields as the parameter.
        random_number = random.randint(100000, 999999)
        self.post_id = f"{random_number}_{self.url}"
        self.authors = []
        for i in range(0, len(author_names)):
            self.authors.append({"id": author_ids[i], "name": author_names[i]})

    def to_json(self):
        json.dumps(asdict(self))

Давайте назовем это снова:

>>> Metadata(
... title="Some Article",
... url="https://example.com/article.html",
... created_at="2018-09-23",
... author_names=["Furkan Kalkan", "John Doe"],
... author_ids=["1", "2"]
... )
Metadata(title='Some Article', url='https://example.com/article.html', created_at='2018-09-23', authors=[{'id': '1', 'name': 'Furkan Kalkan'}, {'id': '2', 'name': 'John Doe'}], post_id='692728_https://example.com/article.html')

Ага!

Но ждать… Где автор_names. и author_ids пропали?

Примечание: Псевдо поля, которые Initvar. экземпляр, используемый только в __post_init __ () В качестве параметров они не являются частью объекта.

>> Metadata.author_names
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: type object 'Metadata' has no attribute 'author_names'

Часть 4: Нам не нужно определять author_names.

Мы можем сделать псевдоэлектрические поля тоже по желанию.

import random, json
from dataclasses import *


@dataclass
class Metadata:
    # Non-nullable Pseudo fields
    author_ids: InitVar[list]
    # Normal fields
    title: str
    url: str
    created_at: str = None
    authors: list = None
    # Nullable Pseudo fields
    author_names: InitVar[list] = field(default=None)
    # Calculated fields
    post_id: str = field(init=False)

    def __post_init__(self, author_names, author_ids): # You have to pass pseudo fields as the parameter.
        random_number = random.randint(100000, 999999)
        self.post_id = f"{random_number}_{self.url}"
        if author_names:
            self.authors = []
            for i in range(0, len(author_names)):
                self.authors.append({"id": author_ids[i], "name": author_names[i]})

    def to_json(self):
        json.dumps(asdict(self))

Назови это:

>>> Metadata(
... title="Some Article",
... url="https://example.com/article.html",
... created_at="2018-09-23",
... author_ids=["1", "2"]
... )
Metadata(title='Some Article', url='https://example.com/article.html', created_at='2018-09-23',authors=None,post_id='692728_https://example.com/article.html')

Часть 5: нам нужно JSON.

Объекты Python хороши, но нам нужно бросить его как JSON, чтобы опубликовать его на веб-сервисы, MQS и т. Д. Библиотека Dataclass встроен в функцию наркоман () который может бросить ваш объект на обдумывать .

Давайте напишем обертку для нашего объекта.

import random, json
from dataclasses import *


@dataclass
class Metadata:
    # Non-nullable Pseudo fields
    author_names: InitVar[list]
    author_ids: InitVar[list]
    # Normal fields
    title: str
    url: str
    created_at: str = None
    authors: list = None
    # Calculated fields
    post_id: str = field(init=False)

    def __post_init__(self, author_names, author_ids): # You have to pass pseudo fields as the parameter.
        random_number = random.randint(100000, 999999)
        self.post_id = f"{random_number}_{self.url}"
        if author_names:
            self.authors = []
            for i in range(0, len(author_names)):
                self.authors.append({"id": author_ids[i], "name": author_names[i]})

    def to_json(self):
        return json.dumps(asdict(self))

Проверь это:

>>> m = Metadata(
... title="Some Article",
... url="https://example.com/article.html",
... created_at="2018-09-23",
... author_names=["Furkan Kalkan", "John Doe"],
... author_ids=["1", "2"]
... )
>>> m.to_json()
{"title": "Some Article", "url": "https://example.com/article.html", "created_at": "2018-09-23", "authors": [{"id": "1", "name": "Furkan Kalkan"}, {"id": "2", "name": "John Doe"}], "post_id": "466969_https://example.com/article.html"}

Часть 6: Удалите ненужные поля с JSON.

Мы хотим удалить Нет Ценные поля от JSON, кроме поля URL. Это возможно с небольшим количеством изменений:

def to_json(self):    
    metadata = asdict(self)
    for key in list(metadata):
        if key != "url" and metadata[key] == None:
                del metadata[key]
    return json.dumps(metadata)

Оригинал: “https://dev.to/furkan_kalkan1/a-fully-automated-metadata-objects-with-python-37s-brand-new-dataclass-library-492i”