2015-02-08 3 views
0

Я считаю себя писать слишком много из них:Как избежать повторения шаблона лямбды в питоне?

upper = lambda c : c.upper() 
lower = lambda c : c.lower() 
foo = lambda a,b : a.foo(b) 

Как я могу избежать или, по крайней мере, свести к минимуму такого шаблонного?

Не было (или не должно быть) там PEP, чтобы разрешать методы передачи/вызова как обычные процедуры?

+4

Зачем вам это нужно? Я не помню, чтобы когда-либо использовал такой шаблон, и у меня есть опыт. Может быть, есть лучший подход. –

+0

Я бы не назвал это шаблоном; единственное, что вы повторно используете, - это ключевое слово lambda. Вы можете использовать 'operator.methodcaller()' или 'functools.partial()', но вы не сохраните себе никаких символов при определении этих объектов. –

+1

один способ не использовать его вообще, не уверен, что я понял его. –

ответ

0

Вы можете использовать несвязанные методы, а не создавать свои собственные функции ,

В ваших первых двух примерах вы, вероятно, захотите str.upper и str.lower. (Если вам необходимо поддерживать более str, вы могли бы использовать operator.methodcaller("upper") или подобное, но имейте в виду, что это почти наверняка плохое дизайнерское решение, чтобы иметь дело с обоими str и bytes объектов с тем же кодом!)

Ваш третий пример сложнее. Если вам нужен только один объект a, вы должны указать его, и он будет работать так же, как и примеры str (например, A.foo). Аналогично, если значение b является постоянным и известно заранее, вы можете использовать operator.methodcaller("foo", b), чтобы получить вызываемый код, который вызывает a.foo(b) для данного значения a, но это не помогает, если b также является переменной.

Если вы не знаете a или b заранее, вам действительно нужно придерживаться функции.Если вам не нравится, как лямбда-выражение выглядит, вы можете использовать обычное def заявление:

def foo(a, b): 
    return a.foo(b) 

Если это то, что вы часто используете, вы можете написать свой собственный вариант на methodcaller производить функции по требованию:

def my_methodcaller(method_name): 
    def inner(obj, *args, **kwargs): 
     return getattr(obj, method_name)(*args, **kwargs) 
    return inner 

Затем вы должны использовать foo = my_methodcaller("foo").

4

Я действительно не понимаю, что вы решаете. Вы просто меняете свои методы из

'abc'.upper() 

в

upper('abc') 

Это на самом деле не получить вам что-нибудь, на самом деле это немного менее читабельным. Если вы используете для передачи в другие методы лямбда в качестве key вы можете просто сделать что-то вроде

l = ['ab', 'Aa', 'ca'] 
sorted(l, key = str.upper) 

Обратите внимание, что я могу просто позвонить str.upper без определения lambda

2

Как можно избежать или, по крайней мере, минимизировать такой шаблон?

Просто не используйте его! Или, более конкретно:

  • Использование c.upper() вместо upper(c)
  • Использования c.lower() вместо lower(c)
  • Использование a.foo(b) вместо foo(a, b)
+0

Преимущество функциональных объектов заключается в том, что вы можете хранить их в сопоставлении и динамически применять их. Для них есть *. –

+0

Я согласен, но его примеры, особенно «a.foo (b)», предполагают, что его цель состоит в том, чтобы работать с использованием методов в классическом смысле, потому что ему нравится «функциональный» подход , Если его целью является применение методов в виде карты, то я думаю, что у нас есть лучший совет, например, использование списков. –

Смежные вопросы