Как лучше всего передать метод (с параметрами) другому методу в python? - PullRequest
2 голосов
/ 01 апреля 2009

Как лучше всего передать метод и параметр метода другому методу?

Есть ли лучший способ сделать следующее?

def method1(name)
    return 'Hello ' + name

def method2(methodToCall, methodToCallParams, question):
    greetings = methodToCall(methodToCallParams)
    return greetings + ', ' + question

method2(method1, 'Sam', 'How are you?')

Ответы [ 5 ]

11 голосов
/ 01 апреля 2009

Если вы хотите упаковать вызов в один удар, вы можете использовать модуль functools:

from functools import partial

def some_function(param_one, param_two):
    print "Param One: %s" % param_one
    print "Param Two: %s" % param_two

def calling_function(target):
    target()

calling_function(partial(some_function, "foo", "bar"))

Вы также можете делать более тонкие вещи с помощью functools.partial, например связывать только некоторые параметры, оставляя вам функцию с новой сигнатурой. Во многих случаях использовать его излишне, но, безусловно, оно имеет место.

3 голосов
/ 01 апреля 2009

Вы можете сделать это так:

def method1(name):
    def wrapper():
        return 'Hello ' + name
    return wrapper

def method2(method, question):
    output = method()
    return output + ', ' + question

method2(method1(name = 'Sam'), 'How are you?')

Конечно, вы можете передавать и некоторые переменные в вызове метода ():

def method1(name):
    def wrapper(greeting):
        return greeting + name
    return wrapper

def method2(method, question):
    output = method(greeting = 'Hello ')
    return output + ', ' + question

method2(method1(name = 'Sam'), 'How are you?')
2 голосов
/ 02 апреля 2009

Вы можете использовать functools.partial , чтобы сделать это, как указано jkp

Тем не менее, functools является новым в Python 2.5, поэтому для обработки этого в прошлом я использовал следующий код (на самом деле этот код находится в документации по Python для functools.partial).

# functools is Python 2.5 only, so we create a different partialfn if we are
# running a version without functools available
try:
    import functools
    partialfn = functools.partial
except ImportError:
    def partialfn(func, *args, **keywords):
        def newfunc(*fargs, **fkeywords):
            newkeywords = keywords.copy()
            newkeywords.update(fkeywords)
            return func(*(args + fargs), **newkeywords)
        newfunc.func = func
        newfunc.args = args
        newfunc.keywords = keywords
        return newfunc
1 голос
/ 01 апреля 2009

Другой вариант, если вы работаете над Python версии до 2.5, это использовать лямбду в качестве замыкания:

def some_func(bar):
    print bar

def call_other(other):
    other()

call_other(lambda param="foo": some_func(param))

НТН

0 голосов
/ 01 апреля 2009

Вы думаете о карри, где вы связываете вместе функцию и аргументы для последующего вызова. Обычно каррирование используется для добавления дополнительных аргументов во время фактического вызова функции.

Вместо того, чтобы переписать колесо, вот ссылка на пример: http://code.activestate.com/recipes/52549/.

Если, однако, случай, который вы смоделировали в вопросе, действительно настолько прост, вы можете передать список аргументов в качестве позиционных параметров или список kwargs в качестве именованных параметров другой функции.

def method1(name):
    return 'Hello %s' % name

args = ['Joe']
method1(*args)

def method1a(name=None, salutation=None):
    return 'Hello %s %s' % (name, salutation)

kwargs = {'name':'Joe', 'salutation':'Mr'}
method1a(**kwargs)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...