** механизм поиска kwargs в объекте (python) - PullRequest
0 голосов
/ 02 ноября 2009

Хотите иметь возможность предоставлять интерфейс поиска для коллекции объектов, используя список аргументов ключевых слов, например:

playerID = players.search(nameFirst='ichiro', nameLast='suzuki')

Где Players.search определяется следующим образом:

def search(self, **args):
    ret = []
    for playerID, player in self.iteritems():
        for key, value in args.iteritems():
            if getattr(player, key) == value:
                ret.append(player.playerID)

    return ret

Очевидно, что приведенный выше код не работает. Я хочу, чтобы позаимствовать некоторые идиомы SQL, работать так, где player.key == value и player.keyN = valueN и т. Д. Для числа N переданных kwargs.

Есть идеи? Спасибо!

Ответы [ 2 ]

1 голос
/ 02 ноября 2009

Я хочу заимствовать некоторые идиомы SQL, работать как где player.key == значение и player.keyN = valueN и т. д. для N количество пройденных kwargs.

Итак, вы в настоящее время внедряете ИЛИ и хотите вместо него реализовать И - это так?

Если так, то all, предложенный в ответе @ Mark, будет работать - или альтернативно, и эквивалентно, хотя и на более низком уровне абстракции:

def search(self, **args):
  ret = []
  for playerID, player in self.iteritems():
    for key, value in args.iteritems():
      if getattr(player, key) != value: break
    else:
       ret.append(player.playerID)

  return ret

Я не совсем уверен, почему вы зацикливаетесь на iteritems, а затем игнорируете ключ, который получаете (добавляя player.playerID вместо ключа playerID напрямую).

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

def search(self, **args):
  def vals(p):
    return dict((k, getattr(p, k, None)) for k in args)
  return [p.playerID for p in self.itervalues() if vals(p) == args]

Этот не "закорачивает", но в остальном эквивалентен Марку. Полностью эквивалентный, но довольно лаконичный:

def search(self, **args):
  return [p.playerID for p in self.itervalues()
          if all(getattr(p, k, None)==args[k] for k in args)]

Если эти фрагменты кода не соответствуют вашим потребностям, и вы можете уточнить, почему именно они не соответствуют (в идеале, примером или тремя! -), я уверен, что их можно настроить для удовлетворения указанных потребностей.

1 голос
/ 02 ноября 2009

Вы должны быть в состоянии изменить его на понимание списка с помощью встроенного all, который возвращает True, если все элементы в его аргументе верны (или, если итерация пуста). Нечто подобное должно сработать:

for playerID, player in self.iteritems():
    if all(getattr(player, key) == value for key, value in args.iteritems()):
         ret.append(player.playerID)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...