Как программно передать ключевые слова для работы в Python? - PullRequest
0 голосов
/ 04 сентября 2018

У меня есть код, который я пытаюсь реорганизовать, который выглядит примерно так в Python 3:

  # some_obj.query(streetaddress="burdon")
  # some_obj.query(area="bungo")
  # some_obj.query(region="bingo")
  # some_obj.query(some_other_key="bango")

Как я могу высушить это, чтобы у меня было что-то вроде этого?

# define a list of tuples like so:
set_o_tuples = [
  ("streetaddress", "burdon")
  ("area", "bungo"),
  ("region", "bingo"),
  ("some_other_key", "bango"),
])

А затем вызвать его в функции

for key, val in set_o_tuples:      
  some_obj.query(key=val)

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

SyntaxError: keyword can't be an expression

Что является идиоматическим способом СУШИТЬ это, так что мне не нужно повторять загрузки кода, как в примере выше?

Обновление: извините, ребята, я думаю, что приведенный выше пример пропустил несколько важных деталей. У меня в основном есть какой-то код pytest, такой как

def test_can_search_by_location(self, db, docs_from_csv):
    """
    We want to be able to query the contents of all the below fields when we query by location:
    [ streetaddress, locality, region, postcode]
    """

    search = SomeDocument.search()

    locality_query = search.query('match', locality="some val")
    locality_res = locality_query.execute()

    region_query = search.query('match', region="region val")
    region_query_res = region_query.execute()

    postcode_query = search.query('match', postcode="postcode_val")
    postcode_query_res = postcode_query.execute()

    streetaddress_query = search.query('match', concat_field="burdon")
    field_query_res = field_query.execute()

    location_query = search.query('match', location=concat_value)
    location_query_res = location_query.execute()

    assert len(locality_query_res) == len(location_query_res)
    assert len(region_query_res) == len(location_query_res)
    assert len(streetaddress_query_res) == len(location_query_res)
    assert len(postcode_query_res) == len(location_query_res)

Я пытался высушить некоторые из них, поскольку у меня есть похожие примеры, но после прочтения комментариев я переосмыслил это - экономия в космосе на самом деле не оправдывает изменения. Спасибо за указатели.

Ответы [ 2 ]

0 голосов
/ 04 сентября 2018

Вместо этого вы можете определить список словарей, а затем распаковать их при вызове метода в цикле:

list_of_dicts = [
    {"streetaddress": "burdon"}
    {"area": "bungo"},
    {"region": "bingo"},
    {"some_other_key": "bango"},
]

for kwargs in list_of_dicts:      
    some_obj.query(**kwargs)
0 голосов
/ 04 сентября 2018

Использовать распаковка словаря

some_obj.query(**{key: val})

Я бы не советовал, что вы делаете. Оригинальный метод чист и очевиден. Ваш новый может сбить с толку. Я бы оставил все как есть. Это выглядит как плохо спроектированный Python API, some_obj.query должен просто принимать несколько аргументов ключевого слова в одной функции. Вы можете сделать свой собственный, как это:

def query(obj, **kwargs):
    # python 3.6 or later to preserve kwargs order
    for key, value in kwargs.items():
        obj.query(**{key: value})

А потом звонить вот так

 query(some_obj, streetaddress='burdon', area='bungo', region='bingo', some_other_key='bango')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...