Найти - Пользователи
Полная версия: алиас на функцию с частичной подстановкой
Начало » Python для экспертов » алиас на функцию с частичной подстановкой
1 2
pupkin2
всем привет.

ситуация: есть функция, к примеру foo(arg1, arg2). аргумент arg2 может иметь четыре значения. функция используется очень часто.
вопрос: можно ли создать четыре алиаса на функцию, каждый из которых подставлял в качестве второго аргумента соответствующее ему значение?

решение влоб:
def foo(arg1, arg2): pass

def foo_one(arg1): return foo(arg1, "one")
def foo_two(arg1): return foo(arg1, "two")
def foo_three(arg1): return foo(arg1, "three")
def foo_five(arg1): return foo(arg1, "five")
но не хочется плодить сущности.

спасибо.
fanatid
functools.partial ?

import functools
def test(arg1, arg2):
print arg1, arg2
fs = [functools.partial(test, i) for i in xrange(4)]
for i, f in enumerate(fs):
f(i)
pupkin2
fanatid
functools.partial ?
да..почти..
import functools

def foo(arg1, arg2): print arg1, arg2

funcs = [functools.partial(foo, arg2=i) for i in ["one", "two", "three", "four"]]

funcs[0](1)
funcs[1](2)
funcs[2](3)
funcs[3](4)
http://liveworkspace.org/code/b113bb0d7f5c269f3e417e0b475cfba0

вывод:
1 one
2 two
3 three
4 four
теперь остался вопрос в том, как я могу вызвать функцию не извлекая ее из списка?
pupkin2
вроде понял:
import functools

def foo(arg1, arg2): print arg1, arg2

foo_one = functools.partial(foo, arg2="one")
foo_two = functools.partial(foo, arg2="two")
foo_three = functools.partial(foo, arg2="three")
foo_four = functools.partial(foo, arg2="four")

foo_one(1)
foo_two(2)
foo_three(3)
foo_four(4)
http://liveworkspace.org/code/0feaf68b56ee43dcbe43da3de92a087e
pupkin2
тогда возник другой вопрос: как можно сделать то что в последнем коде, но используя список слов?
fanatid
Воспользоваться разыменованием.

import functools

def foo(arg1, arg2): print arg1, arg2

foo_one, foo_two, foo_three, foo_four = [functools.partial(foo, arg2=i) for i in ["one", "two", "three", "four"]]
pupkin2
fanatid, та нет же. в таком случае суффиксы придется писать руками.
а хочется чтоб суффиксы брались из списка.
pill
>>> import sys
... import functools
...
... def foo(arg1, arg2):
... print arg1, arg2
>>> module = sys.modules[__name__]
>>> [setattr(module, 'foo_%s' % i, functools.partial(foo, arg2=i)) for i in ["one", "two", "three", "four"]]
0: [None, None, None, None]
>>> foo_one
1: <functools.partial object at 0xb739a34c>
>>> foo_one(1)
1 one
Но как по мне это грязновато и неинтуитивно.
лучше наверное в словарь загнать и радоваться жизни
>>> import functools
...
... def foo(arg1, arg2): print arg1, arg2
...
... funcs = {'foo_' + i: functools.partial(foo, arg2=i) for i in ["one", "two", "three", "four"]}
>>> funcs['foo_one']('blah')
blah one
pupkin2
pill
Но как по мне это грязновато и неинтуитивно.
лучше наверное в словарь загнать и радоваться жизни
действительно.

pill
funcs = {'foo_' + i: functools.partial(foo, arg2=i) for i in }
хех… до генерирования словарей я еще не дошел :)

pill, спасибо. на варианте со словарем остановлюсь.
doza_and
одно из мощных(и опасных) средств для разных языков семейство exec,eval. Оно зачастую и проще выглядит.
for x in "x1 x2 x3".split():
exec("""def {nm}(i):print '{nm}'+str(i)""".format(nm=x))
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB