我在python中偶然发现了一个我很难理解的行为.这是概念验证代码:
from functools import partial
if __name__ == '__main__':
sequence = ['foo', 'bar', 'spam']
loop_one = lambda seq: [lambda: el for el in seq]
no_op = lambda x: x
loop_two = lambda seq: [partial(no_op, el) for el in seq]
for func in (loop_one, loop_two):
print [f() for f in func(sequence)]
Run Code Online (Sandbox Code Playgroud)
以上的输出是:
['spam', 'spam', 'spam']
['foo', 'bar', 'spam']
Run Code Online (Sandbox Code Playgroud)
行为loop_one对我来说是令人惊讶的,因为我希望它表现为loop_two:el是一个在每个循环中改变的不可变值(一个字符串),但lambda似乎存储一个指向"循环变量"的指针,就好像循环将循环序列中每个元素的相同内存地址.
上面的行为与包含for循环的完整函数相同(因此它不是列表理解语法).
但是等等:还有更多......更令人费解!
以下脚本的工作方式如下loop_one:
b = []
for foo in ("foo", "bar"): …Run Code Online (Sandbox Code Playgroud) 为什么尝试创建curried函数列表不起作用?
def p(x, num):
print x, num
def test():
a = []
for i in range(10):
a.append(lambda x: p (i, x))
return a
>>> myList = test()
>>> test[0]('test')
9 test
>>> test[5]('test')
9 test
>>> test[9]('test')
9 test
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?
实际上我希望上述函数执行的功能是:
import functools
def test2():
a = []
for i in range (10):
a.append(functools.partial(p, i))
return a
>>> a[0]('test')
0 test
>>> a[5]('test')
5 test
>>> a[9]('test')
9 test
Run Code Online (Sandbox Code Playgroud) 我对Eli Bendersky给出的这个例子感到有些惊讶(http://eli.thegreenplace.net/2015/the-scope-of-index-variables-in-pythons-for-loops/)
>>> def foo():
... lst = []
... for i in range(4):
... lst.append(lambda: i)
... print([f() for f in lst])
...
>>> foo()
[3, 3, 3, 3]
Run Code Online (Sandbox Code Playgroud)
但是当我想到它时,它有一定道理 - lambda正在捕捉对i的引用,而不是我的价值.
所以解决这个问题的方法如下:
>>> def foo():
... lst = []
... for i in range(4):
... lst.append((lambda a: lambda: a)(i))
... print([f() for f in lst])
...
>>> foo()
[0, 1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
似乎这个工作的原因是,当我被提供给外部lambda时,外部lambda创建一个范围并取消引用i,将a设置为i.然后,返回的内部lambda保持对a的引用.
这是正确的解释吗?
版问题:
上下文菜单应动态显示过滤器变量,并使用回调内定义的参数执行函数.通用描述显示正确,但函数调用始终使用last set选项执行.
我尝试过的:
#!/usr/bin/env python
import Tkinter as tk
import ttk
from TkTreectrl import MultiListbox
class SomeClass(ttk.Frame):
def __init__(self, *args, **kwargs):
ttk.Frame.__init__(self, *args, **kwargs)
self.pack(expand=True, fill=tk.BOTH)
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
self.View=MultiListbox(self)
__columns=("Date","Time","Type","File","Line","-","Function","Message")
self.View.configure(columns=__columns, expandcolumns=(0,0,0,0,0,0,0,1))
self.View.bind("", self.cell_context)
self.View.grid(row=0, column=0, sticky=tk.NW+tk.SE)
self.__recordset = []
self.__recordset_filtered = False
#Some dummy values
self.__recordset.append(["Date", "Time", "INFO", "File", "12", "-", "Function", "Message Info"])
self.__recordset.append(["Date", "Time", "DEBUG", "File", "12", "-", "Function", "Message Info"])
self.__recordset.append(["Date", "Time", "WARNING", "File", "12", "-", "Function", "Message Info"])
self.__refresh()
def cleanView(self):
self.View.delete(0, …Run Code Online (Sandbox Code Playgroud) 我在我的网站上的一些页面上有一个评论部分,我用一个{% for ... %}循环构建(还有另一个用于评论回复的嵌套循环。该部分被黑客攻击在一起,我仍在学习 Web 开发和 Django,所以请原谅任何令人沮丧的草率或怪异. 我现在不关心效率,只关心效率,现在还不太合适。
对于每条评论,我都有一个 Bootstrap 下拉按钮,可以显示选项Edit和Delete. Edit将打开一个模式来编辑评论。模态是用{% include %}标签呈现的。下面我包含了未修改的部分代码,而不是试图简化我的示例并冒着遗漏一些重要内容的风险:
<div class="panel panel-default">
{% for comment in spot.ordered_comments %}
<div class="panel-heading row">
<div class="col-sm-10">
<strong>{{ comment.poster.username }}</strong>
<em style="margin-left: 2em">{{ comment.created|date:'M d \'y \a\t H:i' }}</em>
</div>
<div class="btn-group col-sm-2" role="group">
{% if comment.poster == user %}
<form id="delete-comment-form" class="form"
method="post" action="{% url 'delete_comment' spot.id comment.id %}">
{% csrf_token %}
</form>
{% include 'topspots/editmodal.html' with edit_type='comment' %} …Run Code Online (Sandbox Code Playgroud) 何时进行懒惰评估?(生成器,如果是迭代器?),什么时候延迟绑定?(关闭,常规功能?)
a = [1,2,3,4]
b = [lambda y: x for x in a]
c = (lambda y: x for x in a) #lazy evaluation
d = map(lambda m: lambda y:m, a) #closure
for i in b:
print i(None)
# 4 4 4 4
for i in c:
print i(None)
# 1 2 3 4
for i in d:
print i(None)
# 1 2 3 4
Run Code Online (Sandbox Code Playgroud) 我在Python hitchhikers 指南中看到了这个例子:
def create_multipliers():
return [lambda x, i=i : i * x for i in range(5)]
Run Code Online (Sandbox Code Playgroud)
上面的示例是对后期绑定引起的一些问题的解决方案,其中在调用内部函数时查找闭包中使用的变量。
i=i 是什么意思以及为什么会产生如此大的差异?
我已经浏览了所有关于动态属性设置的 Stackoverflow 答案,但无论出于何种原因,我似乎无法让它发挥作用。
我有一个类,Evolution_Base它在其中init创建了一个实例Value_Differences。Value_Differences应该properties根据我传递的列表动态创建,从以下位置返回函数值_get_df_change:
from pandas import DataFrame
from dataclasses import dataclass
import pandas as pd
class Evolution_Base():
def __init__(self, res_date_0 : DataFrame , res_date_1 : DataFrame):
@dataclass
class Results_Data():
res_date_0_df : DataFrame
res_date_1_df : DataFrame
self.res = Results_Data(res_date_0_df= res_date_0,
res_date_1_df= res_date_1)
property_list = ['abc', 'xyz']
self.difference = Value_Differences(parent = self, property_list=property_list)
# Shared Functions
def _get_df_change(self, df_name, operator = '-'):
df_0 = getattr(self.res.res_date_0_df, df_name.lower())
df_1 = getattr(self.res.res_date_1_df, …Run Code Online (Sandbox Code Playgroud) 在最近的Hacker Newsletter问题中,这篇关于Python中装饰器的非常有用的文章已被链接.我喜欢这篇文章,我想我理解了大多数装饰器的例子.但是,在非装饰器的memoization示例中,我对代码非常困惑:
def memoize(fn):
stored_results = {}
def memoized(*args):
try:
# try to get the cached result
return stored_results[args]
except KeyError:
# nothing was cached for those args. let's fix that.
result = stored_results[args] = fn(*args)
return result
return memoized
Run Code Online (Sandbox Code Playgroud)
我很困惑这个函数如何创建一个stored_results附加到的持久字典.重新阅读后,将其复制/粘贴到我的编辑器中并使用它,并在网上寻求帮助,我仍然不明白语法stored_results[args] = fn(*args)是做什么的.
(1)文章建议上面的代码将返回函数,但现在它将在执行新的参数之前首先搜索字典.这是怎么发生的?为什么不stored_results只是当地人memoize?memoized返回时为什么不被销毁?
(2)解释通过这里的论点的其他问题或网络资源的链接*args也会有所帮助.如果*args是参数列表,为什么我们可以使用语法 stored_results[args],通常在尝试索引列表中的字典时会出现不可出错的错误?
感谢任何澄清的想法.
在列表理解中使用闭包时,我发现了这个:
xs = [1, 2, 3]
fs = [lambda: _ for _ in xs]
vs = [_() for _ in fs]
print vs # [<function <lambda> at 0x020324B0>, <function <lambda> at 0x020D6AB0>, <function <lambda> at 0x020D6AF0>]
print vs[0] # <function <lambda> at 0x020324B0>
print vs[0]() # <function <lambda> at 0x020D6AF0>
print vs[0]()() # <function <lambda> at 0x020D6AF0>
print vs[0]()()() # <function <lambda> at 0x020D6AF0>
Run Code Online (Sandbox Code Playgroud)
不应该vs包含ints而不是lambdas?
但是如果我们在两个列表推导中使用不同的名称,它将按预期工作:
xs = [1, 2, 3]
fs = [lambda: …Run Code Online (Sandbox Code Playgroud) python ×10
lambda ×6
closures ×2
python-2.7 ×2
contextmenu ×1
django ×1
function ×1
late-binding ×1
loops ×1
memoization ×1
scope ×1
tkinter ×1