Область действия лямбда-функции при передаче в другой модуль - PullRequest
2 голосов
/ 19 сентября 2019

Я пытаюсь обернуть голову вокруг объема функций лямбды.Я заметил, что я могу создать лямбда-функцию в одном модуле A и передать ее функции в другом модуле B , но могу вызывать функции из модуля A ,

Является ли это плохой практикой передавать лямбда-функции таким образом, или есть более предпочтительный (передовой метод) метод для обработки этого?

target.py

class TestLambda():

    def __init__(self,name):
        self.name = name

    def call(self,func):
        func(self.name)

source.py

from target import TestLambda

def sayHello(name):
    print("Hello {}".format(name))

func = lambda n: sayHello(n)

l = TestLambda("John")
l.call(func)

выход

➜  lambda-test python3 source.py
Hello John

Ответы [ 2 ]

2 голосов
/ 19 сентября 2019

Ключевым моментом здесь является то, что каждый объект function содержит ссылку на область, в которой функция была определена .

>>> func.__globals__['sayHello']
<function sayHello at 0x1085f2680>

Это то, что позволяет func по-прежнему вызыватьsayHello даже при вызове из функции с другой глобальной областью действия.Поиск по названию static ;они зависят только от лексического (статического) контекста, в котором появляются имена, а не от динамического контекста времени выполнения.Есть языки (Lisp, shell и т. Д.), В которых используется динамическая область видимости;Тем не менее, лексическая или статическая область видимости широко рассматривается как более легкая для рассуждения.

0 голосов
/ 19 сентября 2019

Я не думаю, что есть какие-либо проблемы с созданием и передачей лямбда-функций, в отличие от использования

def func(name):

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

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

Документы Python специально не поощряют это :

Всегда используйте оператор def вместо оператора присваивания, который связывает лямбда-выражение напрямую с идентификатором.

Да:

def f(x): return 2*x

Нет:

f = lambda x: 2*x

Первая форма означает, что имя получающегося функционального объекта определенно 'f' вместоиз общего ".Это более полезно для трассировок и строковых представлений в целом.Использование оператора присваивания исключает единственное преимущество, которое лямбда-выражение может предложить по сравнению с явным оператором def (то есть то, что оно может быть встроено в большее выражение)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...