2009-10-09 3 views
4

Интересно, есть ли хороший способ привязать локальные переменные в python. Большая часть моей работы связана с сборкой коротких сценариев обработки данных или текстовой обработки с помощью ряда выражений (когда разрешен python), поэтому определение классов объектов (для использования в качестве пространств имен) и их создание кажется немного большим.привязка локальных переменных в python

Так что я имел в виду что-то вроде в (общий) шепелявость, где вы могли бы сделать что-то вроде

(setq data '(1 2 3)) 
(setq output 
     (let ((x (nth 2 data))) 
     x + x)) 

В питона, лучшее, что я мог придумать это

data = [1,2,3] 
output = ((lambda x: x + x) 
      (data[2])) 

Это, конечно, очень простые примеры, но может ли быть что-то такое же масштабируемое, как let или let * в lisp? Являются ли определяющие классы лучшим способом для создания локального пространства имен? ... (но чувствует себя немного менее интерактивным)

Редактировать: Поэтому, чтобы далее объяснить намерение (мои извинения за неопределенность), я хочу для уменьшения использования глобальных переменных. Поэтому в приведенном выше случае я хотел использовать оператор извлечения как общий случай любого типа операции, который, возможно, не захочет повторять. Например, можно было бы написать либо

output = data[2] + data[2] 

или

x = data[2] 
output = x + x 
del x 

для достижения такого же результата. В сущности, если желаемая операция над «данными» более сложна, а затем получает второй элемент, я бы не хотел вводить его несколько раз или позволить компьютеру вычислить значение того же выражения больше раз, чем это необходимо. Поэтому в большинстве случаев присваивать результат операции, в данном случае, данные [2] или operator.itemgetter (2) (данные), некоторой переменной в глобальном пространстве, но у меня есть отвращение к остающимся переменным вокруг в глобальном пространстве, если они необходимы только для хранения промежуточных значений при вычислении ... следовательно, использование команды «del» сразу после этого. Определение локальной среды или пространства имен и промежуточных результатов привязки к локальным переменным было бы идеальной альтернативой.

+0

ОК, обновил свой ответ. –

ответ

3

я могу только второй Леннарт и Даниэль - Python не Lisp, и, пытаясь написать язык X на язык Y, обычно неэффективен и расстраивает в лучшем случае.

Первая точка: ваш пример кода

data = [1,2,3] 
output = ((lambda x: x + x) 
      (data[2])) 

будет гораздо более удобным для чтения, как:

data = [1, 2, 3] 
output = (lambda x=data[2] : x +x)() 

, но в любом случае, в этом конкретном случае, с помощью лямбда тотально излишеством, overcomplexificated, и в основном неэффективен. Braindead

output = data[2] + data[2] 

бы JustWork (тм) -!)

Теперь WRT/местные переплеты/пространства имен, обычное решение является использование ... функции - в конце концов, вложенный. В то время как объект 100% (как и во «все является объектом»), Python не является чистым объектом, а простые функции просто прекрасны. FWIW, даже для «скриптов», вы должны поместить свою логику в функцию, а затем вызвать ее - доступ к локальному пространству имен функции быстрее, чем «глобальный» (действительно: уровень модуля) доступ к пространству имен. Каноническая картина

import whatever 

def some_func(args): 
    code_here 

def some_other_func(args) 
    code_here 

def main(args): 
    parse_args 
    some_func(something) 
    some_other_func(something_else) 
    return some_exit_code 

if __name__ == '__main__' 
    import sys 
    sys.exit(main(sys.argv))   

Заметим также, что вложенные функции могут также получить доступ к охватывающую пространство имен, т.е.

def main(): 
    data = [1, 2, 3] 
    def foo(): 
     x = data[2] 
     return x + x 
    print foo() 
    data = [4, 5, 6] 
    print foo() 
    # if you want the nested function to close over its arguments: 
    def bar(data=data): 
     x = data[2] 
     return x + x 
    print bar() 
    data = [7, 8, 9] 
    print bar() 

НТН

+0

Спасибо! Да. Я знаю правила лексики для Python с 2.4 (?) ... но надеялся, что смогу сделать гораздо больше без названных функций. Но спасибо за иллюстрации. – hatmatrix

+0

Поддержка Python для функционального программирования действительно очень ограничена - но, эй, Python не претендует на роль функционального языка. –

1

Не зная Лиспа, я не вижу, что вы пытаетесь сделать здесь. Но я бы сказал, что в целом вы не должны пытаться писать Python, как если бы это был Lisp, или даже любой язык, как если бы это был какой-либо другой язык. Я программировал на Python в течение пяти лет, и я никогда не видел необходимости делать то, что вы пытаетесь сделать выше.

Можете ли вы привести пример использования для вышеуказанного - что вы на самом деле пытаетесь сделать с точки зрения конечного результата? Возможно, тогда мы сможем посоветовать вам наилучший способ сделать это на Python, а не на Lisp.

2

Это немного неясно, что вы просите, я немного постараюсь ответить так или иначе:

Вы связывать переменные с именами с = в Python. Итак, ваш data = [1,2,3] связывает список [1,2,3] с именем data.

Вы можете создать локальные пространства имен с классами и функциями/методами.

Ближайший источник: let, возможно, def и lambda. Python (несмотря на то, что некоторые люди пытаются рассказать вам), а не Lisp, и не особенно функциональны, так что вам придется немного адаптировать свое мышление.

Обновление: Ах, я понимаю, что вы имеете в виду сейчас.

Все переменные являются довольно локальными в Python. Ближайшие к глобальным переменным переменные - это переменные, определенные в пространстве модулей, потому что вы можете получить к ним доступ с помощью from <module> import <variable>. Вы также можете получить к ним доступ где бы то ни было в модуле, но не изменять их (если вы не скажете, что хотите изменить их с помощью ключевого слова global. Все, что вы определяете в определении функции/метода или класса, будет доступно только из этого пространства имен.

Так короче:.. Вам не придется беспокоиться о вещах, которые вы беспокоиться о теперь Python заботится о нем для вас :)

+0

Я бы даже сказал, что Python пытается так сильно, как не может быть Lisp. – Svante

+0

Хм, я так не думал об этом! но я предполагаю, что в конце переменная, не заключенная в функцию или модуль, может быть либо перезаписана, либо неправильное (неожиданное) значение может быть вызвано далее в скрипте? Жесткий ... Большое спасибо! – hatmatrix

2

Вы можете совместить функции декоратор и по умолчанию параметры, чтобы получить что-то вроде аренды и переменные с охватом блоков:

def let(func): 
    return func() 


data = [1,2,3] 
@let 
def output(x=data[2]): 
    return x + x 
print(output) # 6 

# or if a single expression is enough: 
output = let(lambda x=data[2]: x+x) 

Но th это не популярная идиома в Python, поэтому я советую вам избежать этого, чтобы сделать код более понятным для других. Просто используйте обычные локальные переменные:

data = [1,2,3] 
x = data[2] 
output = x + x 

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

+0

Спасибо! ... но упоминаемые вами «обычные локальные переменные» не являются локальными, если они не определены в рамках функции или - что-то вроде среды let() ... – hatmatrix

+0

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

Смежные вопросы