Python эквивалент цитаты в LISP

В Python, что эквивалентно оператору кавычки? Я нахожу необходимость отложить оценку. Например, предположим, что в следующем lisp psuedocode у меня есть:

a = '(func, 'g)
g = something
(eval a)

Что я делаю, так это отложенную оценку g до более позднего времени. Это необходимо, потому что я хочу определить g потом. Какова эквивалентная идея этого псевдокода в Python?

2 ответа

Решение
a = lambda: func(g)
g = something
a()

Это не самый буквальный перевод - самый буквальный перевод будет использовать строку и eval - но это, вероятно, лучше всего подходит. Цитировать, вероятно, совсем не то, что вы хотели в Лиспе; Вы, вероятно, хотели delay что-то или создать lambda, Обратите внимание, что func а также g переменные замыкания в lambda функция, а не символы, так что если вы звоните a из среды с разными привязками для func или же g, он все еще будет использовать переменные из aСреда определения.

С помощью eval задерживать оценку плохо, как в Lisp, так и в Python.

в Python и в Lisp вы можете отложить оценку, используя замыкание:

def print_it(x):
    def f():
        print g(x)
    return f

f = print_it(42)

def g(x):
   return x * x

f()

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

fa = []

for x in range(10):
    def g():
        print x
    fa.append(g)

for f in fa:
    f() # all of them will print 9

x = 42

fa[0]() # the output will be 42

Для решения этой проблемы (которая также может присутствовать в Common Lisp) вы можете увидеть такие вещи, как:

for x in range(10):
    def g(x = x):
        print x
    fa.append(g)

или (в CL) такие вещи, как

(let ((a a))
  (lambda () (print a)))

Python также имеет lambda специальная форма для анонимных функций, но они ограничены одним выражением и не могут содержать никаких утверждений. Локально defФункция вместо этого является обычной функцией без каких-либо ограничений.

for x in range(10):
    # print is a statement in Python 2.x and cannot be in a lambda
    fa.append(lambda x=x: sys.stdout.write(str(x) + "\n"))

Наконец, Python 2.x имеет синтаксическое ограничение, а закрытые переменные доступны только для чтения, потому что если в функции есть присваивание (или расширенное присваивание), есть только две возможности:

  1. Переменная является глобальной (и ранее была объявлена global x)
  2. Переменная является локальной

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

Python 3.x снял это ограничение, предоставив новое возможное объявление nonlocal x а теперь знаменитый adder Пример может быть реализован как

def adder(x):
    def f(y):
        nonlocal x
        x += y
        return x
    return f
Другие вопросы по тегам