在python中绑定局部变量

时间:2009-10-09 08:26:24

标签: python lisp

我想知道是否有一种在python中绑定局部变量的好方法。我的大部分工作都涉及将短数据或文本处理脚本与一系列表达式拼凑在一起(当python允许时),因此定义对象类(用作命名空间)并实例化它们似乎有点多。

所以我想到的就是(常见的)lisp,你可以做像

这样的事情
(setq data '(1 2 3))
(setq output 
      (let ( (x (nth 2 data)) )
       x + x))

在python中,我能想到的最好的是

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

这些当然是非常简单的例子,但是在lisp中可能有一些像let或let *一样可伸缩的东西吗?定义类是创建本地命名空间的最佳方式吗?...(但感觉有点不那么交互)

编辑:因此,为了进一步解释意图(我对模糊性的道歉),我想减少全局变量的使用。所以在上面的例子中,我的意思是使用提取运算符作为可能不想重复的任何类型操作的一般情况。例如,可以写一个

output = data[2] + data[2]

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

完成相同的结果。本质上,如果对“数据”的所需操作比获取第二项更复杂,我不想多次输入,或者让计算机计算同一表达式的值超过必要的次数。所以在大多数情况下,人们会将操作的结果(在本例中为data [2]或operator.itemgetter(2)(数据))分配给全局空间中的某个变量,但我厌恶将变量留在周围在全局空间中,如果它们只需要在计算中存储中间值...那么之后立即使用'del'命令。定义本地环境或命名空间并将中间结果绑定到局部变量将是一种理想的替代方法。

4 个答案:

答案 0 :(得分:3)

我只能第二个Lennart和Daniel - 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)()

但无论如何,在这个具体案例中,使用lambda是完全矫枉过正,过度复杂,而且效率最低。脑死亡

output = data[2] + data[2]

JustWork(tm)! - )

现在wrt / to local bindings / namespaces,通常的解决方案是使用...函数 - 最终嵌套。虽然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()

HTH

答案 1 :(得分:2)

有点不清楚你在问什么,我会试着回答:

在Python中使用=将变量绑定到名称。因此,您的data = [1,2,3]会将列表[1,2,3]绑定到名称data

您可以使用类和函数/方法创建本地名称空间。

你得到的最接近的东西就像let一样强大,可能是deflambda。 Python(尽管有些人试图告诉你)不是Lisp,而不是特别功能,所以你必须稍微调整你的思维方式。

更新:啊,我明白你的意思了。

所有变量在Python中几乎是本地的。最接近全局变量的是模块空间中定义的变量,因为您可以使用from <module> import <variable>访问它们。您也可以从模块中的任何位置访问它们,但不能修改它们(除非您说要使用global关键字修改它们。您在函数/方法或类定义中定义的任何内容都只能被访问来自该命名空间。

简而言之:你不必担心你现在担心的事情。 Python会为您处理它。 :)

答案 2 :(得分:2)

您可以组合函数装饰器和默认参数来获取类似let和块范围变量的内容:

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)

但这不是Python中流行的习语,所以我建议你避免它让你的代码更易于理解。只需使用常规局部变量:

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

如果这成为一个真正的问题,那么你试图在一个单一的功能中做太多就是一个好兆头。

答案 3 :(得分:1)

不太了解Lisp,我看不出你在这里想做什么。但我会说,一般来说,你不应该尝试编写Python,好像它是Lisp,或者实际上任何语言都好像是任何其他语言。我已经用Python编程了五年了,我从来没有看到过你需要做的事情。

您能举一个上述用例的例子 - 就最终结果而言,您实际上要做什么?也许那时我们可以建议你用Python做最好的方法,而不是Lisp。