Skip to main content

Easy way to pull out values from a complex nested Python structure

Project description

PullOut.From

Что делает

Извлекает значение из сложносочинённых Python-объектов через цепочку последовательно указанных ключей, атрибутов и индексов.

Зачем

Например, у нас есть такая структура:

our_structure = {
    'structure_name': 'Some name',
    'Python_objects': [
        some_pydatic_structure,
        wsgi_response,
        {
            'another_dict': 11,
            'and_another': 12,
        }
    ],
}

Тут есть всё: словари, списки, объекты с атрибутами. Для навигации по этой структуре нужно использовать различные методы и проверки, и/или обработчики ошибок. Было бы удобно просто по порядку указать ключи, имена атрибутов или целочисленные индексы, и получить конечное значение либо None, если такого пути не существует.

PullOut это позволяет. Самое простое — перечислить аргументы для извлечения через запятую. Класс-обработчик сам определит, атрибут это, ключ или индекс:

from pullout import PullOut

another_dict = PullOut('Python_objects', 2, 'another_dict').From(our_structure)

В этом случае обработчик пройдёт по структуре our_structure и извлечёт значение 11. Он определит, что 'Python_objects' это ключ словаря, 2 это индекс в списке, а another_dict снова ключ.

Так же просто он обработает и атрибуты объектов:

if PullOut(
    'Python_objects', 1, 'status_code'
).From(our_structure) != 200:
    print('Wrong wsgi server response')

Как указывать путь к значению

Как ещё можно передать путь к значению:

  • Через точечную нотацию: 'Python_objects.0.foo.bar'
  • Индексы в точечной нотации могут быть в квадратных скобках: 'Python_objects[0].foo.bar'

Можно прямо указать тип аргумента, что повышает читаемость и не требует автоопределения типа (импортируйте типы из pullout):

  • Attr('attribute_name') (название атрибута объекта)
  • Key(any_valid_key_object) (ключ словаря)
  • Index(any_valid_index_value) (числовой индекс в последовательности)

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

('arg_name.0.key_name[12]', Index(-1), 'arg_name', 'another_name')

Переиспользование

Инструмент задуман таким образом, чтобы готовые паттерны пути можно было описать один раз и затем применять к различным объектам с аналогичными контрактами/протоколами, либо к разным экземплярам одного класса.

get_value_from = PullOut('json', 'my_value', 0).From
extracted_values = [
    get_value_from(response)
    for response
    in wsgi_responses
]

Метод .From может быть заменён простым __call__ при определении общего шаблона с последующим вызовом конкретного объекта. Например, можно декларировать их в том или ином модуле, и импортировать для использования в функционале.

# --- Модуль declarations.py

# Декларировали путь к адресу изображения в некоторой структуре
image_src = PullOut('items', 'images', 0, 'src')


# --- Модуль с функциональностью

from .declarations import image_src

@app.post('/image-src')
def get_image_address(request, some_object: dict):
    return image_src(some_object)

Если потом структуры меняются, открываем декларации и правим пути, а функционал работает, как работал.

Вызов из типизатора

Типы аргументов (Index, Attr или Key) также имеют свои определения метода __call__. Функционально это дублирование инструментов itemgetter, attrgetter и methodcaller из модуля operator стандартной библиотеки Python, и просто для доступа к данным лучше использовать стандартные методы. В нашем случае важно именно указание типа аргумента, а извлечение значения является побочной возможностью. Однако, фокус на типизации может быть полезен (возможно).

Классы-типизаторы способны извлекать значения, если использовать их экземпляры как вызываемые объекты и передавать в них целевой объект:

from pullout import Index


sequence = [1, 2, 3, 4, 5, 100]
first_of, last_of = Index(0), Index(-1)
print(
    first_of(sequence),
    last_of(sequence),
)

>>> 1 100

Примеры есть в документации к этим классам.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pullout-0.1.0.tar.gz (5.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pullout-0.1.0-py3-none-any.whl (6.3 kB view details)

Uploaded Python 3

File details

Details for the file pullout-0.1.0.tar.gz.

File metadata

  • Download URL: pullout-0.1.0.tar.gz
  • Upload date:
  • Size: 5.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.2

File hashes

Hashes for pullout-0.1.0.tar.gz
Algorithm Hash digest
SHA256 5577981e9e8339a60eb2db0275a88d7dcc5dd2eeef04e1dcfe9ae62bbc40959d
MD5 e604643f3216f8023e98da1053e6286c
BLAKE2b-256 0a4f8327bd9f59a999b88f68c9069de57eca473d78fc2e371e0b56d7d10cefd1

See more details on using hashes here.

File details

Details for the file pullout-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pullout-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 6.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.2

File hashes

Hashes for pullout-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 948d7ee59f28e85cc890f5d82b2353768fd36c979312ede5b7f69f312d6bf142
MD5 7ec4707959945c2eb4c68ba18c3a08b8
BLAKE2b-256 6b40c0ffb5c51b16fae4f59b54182f174825f8c8db0d7b913d070c7716c4add0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page