Создание гибкой функции, «x» неопределенная ошибка [дубликат]

Вы можете передать lambda для оценки как условие if.

Попробуйте:

validates :description, presence: true, if: -> { first_step? || require_validation }
14
задан rhormaza 28 November 2012 в 02:23
поделиться

5 ответов

Как насчет:

for name in 'a', 'b', 'c':
    try:
        thing = getattr(obj, name)
    except AttributeError:
        pass
    else:
        break
30
ответ дан wim 21 August 2018 в 17:44
поделиться
  • 1
    Я на самом деле пытался избежать попытки / кроме этого ... Я должен был упомянуть об этом :) – rhormaza 28 November 2012 в 02:51
  • 2
    try / except - типичный пифонический путь, любая хорошая причина, по которой вы хотели его избежать? – wim 28 November 2012 в 04:19
  • 3
    Не какая-то по-настоящему хорошая причина, просто хотел, чтобы код был кратким, и я почувствовал попытку / исключение, но было слишком много :) Другая вещь, которую я проверял сейчас, это то, что блок не предоставляет значение по умолчанию в случае ни одного из этих свойства существуют, хотя это очень маловероятно, но я считаю, что всегда полезно использовать защитный подход :) – rhormaza 28 November 2012 в 05:01
  • 4
    Вы можете сделать это, используя инструкцию else для цикла for, если это то, что вам нужно. Что касается стиля, то в python обычно присутствует множество try / excepts - см. EAFP – wim 28 November 2012 в 05:16
  • 5

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

g = lambda o, l: getattr(o, l[0], g(o, l[1:])) if l else None
0
ответ дан Andrew Clark 21 August 2018 в 17:44
поделиться
  • 1
    Мне очень понравился этот, для простоты и краткости – rhormaza 28 November 2012 в 08:10

Я думаю, что использование dir будет получать по существу то же самое, что __dict__ обычно делает ...

targetValue = "value"
for k in dir(obj):
    if getattr(obj,k) == targetValue:
       print "%s=%s"%(k,targetValue)

что-то вроде

>>> class x:
...    a = "value"
...
>>> dir(x)
['__doc__', '__module__', 'a']
>>> X = x()
>>> dir(X)
['__doc__', '__module__', 'a']
>>> for k in dir(X):
...     if getattr(X,k) == "value":
...        print "%s=%s"%(k,getattr(X,k))
...
a=value
>>>
0
ответ дан Joran Beasley 21 August 2018 в 17:44
поделиться
  • 1
    Спасибо за это, я полностью пропустил dir () ... просто интересно сейчас ... как вызов dir () работает внутри. я проверю – rhormaza 28 November 2012 в 02:56

И еще один:

reduce(lambda x, y:x or  getattr(obj, y, None),  "a b c".split(), None)

(в Python 3 вам нужно импортировать сокращение из functools. Он встроен в Python 2)

-1
ответ дан jsbueno 21 August 2018 в 17:44
поделиться
  • 1
    Это предполагает, что bool(obj.b) имеет значение True. Подумайте, что произойдет здесь, если у вас есть obj.a = 0. Я не думаю, что ты заберешь это. – mgilson 28 November 2012 в 03:15

Это имеет преимущество в работе с любым количеством элементов:

 def getfirstattr(obj, *attrs):
     return next((getattr(obj, attr) for attr in attrs 
                  if hasattr(obj, attr)), None)

У этого есть незначительный недостаток very , который выполняет два поиска по окончательному значению: один раз чтобы убедиться, что атрибут существует, другой для фактического получения значения. Этого можно избежать, используя выражение вложенного генератора:

 def getfirstattr(obj, *attrs):
     return next((val for val in (getattr(obj, attr, None) for attr in attrs)
                  if val is not None), None)

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

2
ответ дан kindall 21 August 2018 в 17:44
поделиться
  • 1
    Я почти что-то сделал с этим. проблема в том, что вы в конечном итоге дважды проверяете нужный элемент (один раз с hasattr и один раз с getattr). В конечном счете, я решил, что это было не лучше, чем явный цикл, отправленный wim. Хотя я открыт для слушания о каких-либо преимуществах, которые могут возникнуть в течение цикла. – mgilson 28 November 2012 в 02:35
  • 2
    Вы можете использовать вложенный генератор, чтобы избежать двойного поиска, я думаю, но это происходит только тогда, когда он находит атрибут, поэтому я считаю его второстепенным недостатком. Однако я добавил такую ​​версию. – kindall 28 November 2012 в 02:36
  • 3
    хороший ... Я собираюсь посмотреть ... – rhormaza 28 November 2012 в 02:52
Другие вопросы по тегам:

Похожие вопросы: