Уведомления

Группа в Telegram: @pythonsu

#1 Ноя. 13, 2011 06:13:30

pupkin2
От:
Зарегистрирован: 2011-10-23
Сообщения: 103
Репутация: +  1  -
Профиль   Отправить e-mail  

алиас на функцию с частичной подстановкой

всем привет.

ситуация: есть функция, к примеру 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")
но не хочется плодить сущности.

спасибо.



Офлайн

#2 Ноя. 13, 2011 07:09:01

fanatid
От:
Зарегистрирован: 2011-09-21
Сообщения: 9
Репутация: +  0  -
Профиль   Отправить e-mail  

алиас на функцию с частичной подстановкой

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)



Офлайн

#3 Ноя. 13, 2011 07:30:06

pupkin2
От:
Зарегистрирован: 2011-10-23
Сообщения: 103
Репутация: +  1  -
Профиль   Отправить e-mail  

алиас на функцию с частичной подстановкой

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
теперь остался вопрос в том, как я могу вызвать функцию не извлекая ее из списка?



Отредактировано (Ноя. 13, 2011 07:37:53)

Офлайн

#4 Ноя. 13, 2011 07:42:10

pupkin2
От:
Зарегистрирован: 2011-10-23
Сообщения: 103
Репутация: +  1  -
Профиль   Отправить e-mail  

алиас на функцию с частичной подстановкой

вроде понял:

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



Офлайн

#5 Ноя. 13, 2011 07:44:07

pupkin2
От:
Зарегистрирован: 2011-10-23
Сообщения: 103
Репутация: +  1  -
Профиль   Отправить e-mail  

алиас на функцию с частичной подстановкой

тогда возник другой вопрос: как можно сделать то что в последнем коде, но используя список слов?



Офлайн

#6 Ноя. 13, 2011 08:03:47

fanatid
От:
Зарегистрирован: 2011-09-21
Сообщения: 9
Репутация: +  0  -
Профиль   Отправить e-mail  

алиас на функцию с частичной подстановкой

Воспользоваться разыменованием.

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"]]



Офлайн

#7 Ноя. 13, 2011 08:05:20

pupkin2
От:
Зарегистрирован: 2011-10-23
Сообщения: 103
Репутация: +  1  -
Профиль   Отправить e-mail  

алиас на функцию с частичной подстановкой

fanatid, та нет же. в таком случае суффиксы придется писать руками.
а хочется чтоб суффиксы брались из списка.



Отредактировано (Ноя. 13, 2011 08:05:44)

Офлайн

#8 Ноя. 13, 2011 09:42:43

pill
От:
Зарегистрирован: 2010-08-27
Сообщения: 223
Репутация: +  0  -
Профиль   Отправить e-mail  

алиас на функцию с частичной подстановкой

>>> 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



Офлайн

#9 Ноя. 13, 2011 09:47:11

pupkin2
От:
Зарегистрирован: 2011-10-23
Сообщения: 103
Репутация: +  1  -
Профиль   Отправить e-mail  

алиас на функцию с частичной подстановкой

pill
Но как по мне это грязновато и неинтуитивно.
лучше наверное в словарь загнать и радоваться жизни
действительно.

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

pill, спасибо. на варианте со словарем остановлюсь.



Офлайн

#10 Ноя. 13, 2011 10:42:52

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  252  -
Профиль   Отправить e-mail  

алиас на функцию с частичной подстановкой

одно из мощных(и опасных) средств для разных языков семейство exec,eval. Оно зачастую и проще выглядит.

for x in "x1 x2 x3".split():
exec("""def {nm}(i):print '{nm}'+str(i)""".format(nm=x))



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version