相关疑难解决方法(0)

词法闭包如何工作?

当我在调查Javascript代码中的词法闭包问题时,我在Python中遇到了这个问题:

flist = []

for i in xrange(3):
    def func(x): return x * i
    flist.append(func)

for f in flist:
    print f(2)
Run Code Online (Sandbox Code Playgroud)

请注意,此示例谨慎避免lambda.它打印"4 4 4",这是令人惊讶的.我期待"0 2 4".

这个等效的Perl代码是正确的:

my @flist = ();

foreach my $i (0 .. 2)
{
    push(@flist, sub {$i * $_[0]});
}

foreach my $f (@flist)
{
    print $f->(2), "\n";
}
Run Code Online (Sandbox Code Playgroud)

打印"0 2 4".

你能解释一下这个区别吗?


更新:

这个问题是不是i是全球性的.这显示相同的行为:

flist = []

def outer():
    for i in xrange(3):
        def inner(x): return x * i …
Run Code Online (Sandbox Code Playgroud)

python closures late-binding lazy-evaluation

144
推荐指数
5
解决办法
3万
查看次数

在循环中创建函数

我正在尝试在循环内创建函数并将它们存储在字典中.问题是字典中的所有条目似乎最终都映射到最后创建的函数.代码如下:

functions = []

for i in range(3):
    def f():
        return i

    # alternatively: f = lambda: i

    functions.append(f)
Run Code Online (Sandbox Code Playgroud)

这输出:

print([f() for f in functions])
# expected output: [0, 1, 2]
# actual output:   [2, 2, 2]
Run Code Online (Sandbox Code Playgroud)

知道为什么吗?

python function

79
推荐指数
2
解决办法
3万
查看次数

使用python中的lambda表达式在循环内生成函数

如果我制作两个函数列表:

def makeFun(i):
    return lambda: i

a = [makeFun(i) for i in range(10)]
b = [lambda: i for i in range(10)]
Run Code Online (Sandbox Code Playgroud)

为什么名单ab不相等?

例如:

>>> a[2]()
2
>>> b[2]()
9
Run Code Online (Sandbox Code Playgroud)

python lambda scope

29
推荐指数
3
解决办法
8761
查看次数

在循环内创建lambda

可能重复:
(lambda)函数闭包在Python中捕获了什么?
lambda函数不关闭Python中的参数?

我试图在循环中创建lambdas迭代一个对象列表:

lambdas_list = []
for obj in obj_list:
   lambdas_list.append(lambda : obj.some_var)
Run Code Online (Sandbox Code Playgroud)

现在,如果我遍历lambdas列表并像这样调用它们:

for f in lambdas_list:
    print f()
Run Code Online (Sandbox Code Playgroud)

我得到了相同的价值.这是最后的价值objobj_list,因为那是在列表迭代器的块中的最后一个变量.任何想法都能很好地(pythonic)重写代码以使其工作?

python

28
推荐指数
3
解决办法
1万
查看次数

如果嵌套在函数中,listcomp无法访问由exec调用的代码中定义的本地

是否有任何python大师能够解释为什么这段代码不起作用:

def f(code_str):
    exec(code_str)

code = """
g = 5
x = [g for i in range(5)]
"""

f(code)
Run Code Online (Sandbox Code Playgroud)

错误:

Traceback (most recent call last):
  File "py_exec_test.py", line 9, in <module>
    f(code)
  File "py_exec_test.py", line 2, in f
    exec(code_str)
  File "<string>", line 3, in <module>
  File "<string>", line 3, in <listcomp>
NameError: name 'g' is not defined
Run Code Online (Sandbox Code Playgroud)

虽然这个工作正常:

code = """
g = 5
x = [g for i in range(5)]
"""

exec(code)
Run Code Online (Sandbox Code Playgroud)

我知道它与locals和globals有关,就好像我从我的主范围传递exec函数locals和globals它工作正常,但我不完全理解发生了什么.

这可能是Cython的一个错误吗?

编辑:尝试使用python 3.4.0和python 3.4.3

python list-comprehension python-exec

10
推荐指数
1
解决办法
389
查看次数

lambda i=i: for 循环中的 foo(i) 不起作用

先读这个。它是关于lambda x=x: foo(x)即使在for循环中也能捕获 x 。

这是一个带有标签和for循环生成的两个按钮的窗口。单击按钮时,它的名称出现在标签中。

如果我们使用 normal lambda: label.setText("button -- " + str(i)),那么结果是 lasti无论按下什么按钮,循环中的:
拉姆达:foo(i)
这是正确的。

当我们改为 lambda i=i: label.setText("button -- " + str(i))(snipet) 并期望现在一切正常时,结果是:
拉姆达 i=i:foo(i)]
错误的!

False是从哪里来的?

import sys
from PyQt4.QtGui import *

class MainWindow(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        vbox = QVBoxLayout(self)

        # label for action
        label = QLabel('')
        vbox.addWidget(label)

        # adding buttons
        for i in range (1, 3):
            btn = QPushButton(str(i))
            btn.clicked.connect( lambda i=i: label.setText("button …
Run Code Online (Sandbox Code Playgroud)

python lambda pyqt

5
推荐指数
1
解决办法
667
查看次数

从PyQt中的QPushButton获取文本

我正在尝试从QtGui.QPushButton对象列表创建一个简单的键盘。

class XKeyboard(QtGui.QWidget):
  '''Special virtual keyboard for any language.'''
  def __init__(self, parent=None):
    QtGui.QWidget.__init__(self, parent)
    self.MainLayout = QtGui.QVBoxLayout()
    self.TextEntry = QtGui.QTextEdit()
    self.Keyboard = QtGui.QVBoxLayout()
    self.MainLayout.addWidget(self.TextEntry)
    self.MainLayout.addLayout(self.Keyboard)
    self.setLayout(self.MainLayout)

  def addRow(self, keys):
    layout = QtGui.QHBoxLayout()
    buttons = [QtGui.QPushButton(unicode(key)) for key in keys]
    for button in buttons:
      key = keys[buttons.index(button)]
      layout.addWidget(button)
      button.clicked.connect(
          lambda key: self.keyClick(key))
      self.keyClick(key)
    self.Keyboard.addLayout(layout)

  def keyClick(self, key):
    self.TextEntry.insertPlainText(key)
Run Code Online (Sandbox Code Playgroud)

问题是lambda返回False而不是键。我究竟做错了什么?

python qt pyqt pyqt4 qt-signals

3
推荐指数
1
解决办法
3612
查看次数

如何将 lambda 附加到 python 中的列表?

我正在尝试制作一个程序来创建格式的 lambda 函数列表y=mx+b,其中“m”和“b”是预先确定的值

我的总体目标是实现一个功能,

  • 拍照
  • 找到上面的线条
  • 以纯色将它们扩展到整个图片

基本上,如果你知道那是什么,像霍夫变换的东西。

一旦我有了特定图像的线条,我就可以创建一个 lambda 函数来表示线条的斜率及其起点。我遇到了无法将 lambda 函数附加到列表的问题。

我试过这个:

if __name__ == "__main__":
  nums = []
  for i in range(10):
    j = lambda x: x + i
    nums.append(j)
  for i in nums:
    print(i(1))
Run Code Online (Sandbox Code Playgroud)

这是我得到的错误:

Traceback (most recent call last):
  File "C:/Users/me/.PyCharmCE2018.3/config/scratches/scratch_3.py", line 7, in <module>
    print(i(1))
  File "C:/Users/me/.PyCharmCE2018.3/config/scratches/scratch_3.py", line 4, in <lambda>
    j = (lambda x: x + i)
TypeError: unsupported operand type(s) for +: 'int' and 'function'
Run Code Online (Sandbox Code Playgroud)

python lambda append

3
推荐指数
2
解决办法
5216
查看次数