我有时会在脚本中的某个位置使用Sub Sample()
Dim oRange As Range, aCell As Range, bCell As Range
Dim ws As Worksheet
Dim ExitLoop As Boolean
Dim SearchString As String, FoundAt As String
On Error GoTo Err
Set ws = Worksheets("Sheet3")
Set oRange = ws.Columns(1)
SearchString = "2"
Set aCell = oRange.Find(What:=SearchString, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not aCell Is Nothing Then
Set bCell = aCell
FoundAt = aCell.Address
Do While ExitLoop = False
Set aCell = oRange.FindNext(After:=aCell)
If Not aCell Is Nothing Then
If aCell.Address = bCell.Address Then Exit Do
FoundAt = FoundAt & ", " & aCell.Address
Else
ExitLoop = True
End If
Loop
Else
MsgBox SearchString & " not Found"
End If
MsgBox "The Search String has been found these locations: " & FoundAt
Exit Sub
Err:
MsgBox Err.Description
End Sub
来快速充实某些本地功能。最小的例子:
embed
开发本地功能通常需要新导入。但是,在函数中使用时,在IPython会话中导入模块似乎不起作用。例如:
#!/usr/bin/env python
# ...
import IPython
IPython.embed()
这相当令人困惑,特别是因为我甚至可以使用制表符完成来编写In [1]: import os
In [2]: def local_func(): return os.path.sep
In [3]: local_func()
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-3-f0e5d4635432> in <module>()
----> 1 local_func()
<ipython-input-2-c530ce486a2b> in local_func()
----> 1 def local_func(): return os.path.sep
NameError: global name 'os' is not defined
。
我注意到问题更为根本:通常,在IPython嵌入会话中创建的函数不会关闭嵌入范围中的变量。例如,这也失败了:
os.path.sep
模块名称可能只是“关闭”最常见的事情......
这个问题有解决办法吗?
更新:问题不仅适用于闭包,还适用于nested list comprehensions。
免责声明:我会自己发布一个(不满意的)问题答案 - 但仍然希望找到更好的解决方案。
答案 0 :(得分:1)
更新:这只是一种解决方法,但有点简单:In [4]: x = 0
In [5]: def local_func(): return x
In [6]: local_func()
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-6-f0e5d4635432> in <module>()
----> 1 local_func()
<ipython-input-5-2116e9532e5c> in local_func()
----> 1 def local_func(): return x
NameError: global name 'x' is not defined
我没有通用的解决方案,但至少有一个解决办法:在定义本地函数之后,可以将globals().update(locals())
会话添加到函数的locals()
刚刚定义,例如:
func_globals
但是,应该知道这只是一个“手动关闭”,在这种情况下不能作为常规关闭:
In [1]: import os
In [2]: def local_func(): return os.path.sep
In [3]: local_func.func_globals.update(locals())
In [4]: local_func()
Out[4]: '/'
至少它可以解决导入的臭名昭着的In [1]: x = 1
In [2]: def local_func(): return x
In [3]: local_func.func_globals.update(locals())
In [4]: local_func()
Out[4]: 1
In [5]: x = 42
In [6]: local_func() # true closure would return 42
Out[6]: 1
In [7]: local_func.func_globals.update(locals()) # but need to update again
In [8]: local_func()
Out[8]: 42
问题。
答案 1 :(得分:1)
我也有同样的问题。我用这个技巧来处理在函数外部调用embed()
时的情况,因此globals()
和locals()
应该是同一词典。
最简单的方法是在启动ipython之后调用以下函数
ipy = get_ipython()
setattr(ipy.__class__, 'user_global_ns', property(lambda self: self.user_ns))
另一种方法是继承InteractiveShellEmbed
class InteractiveShellEmbedEnhanced(InteractiveShellEmbed):
@property
def user_global_ns(self):
if getattr(self, 'embedded_outside_func', False):
return self.user_ns
else:
return self.user_module.__dict__
def init_frame(self, frame):
if frame.f_code.co_name == '<module>':
self.embedded_outside_func = True
else:
self.embedded_outside_func = False
并稍微修改IPython.terminal.embed.embed()
的代码,以便将其中的所有InteractiveShellEmbed
更改为InteractiveShellEmbedEnhanced
,并在行shell.init_frame(frame)
之后调用shell = InteractiveShellEmbed.instance(...)
。
这是基于以下观察结果:
id(globals()) == id(ipy.user_module.__dict__) == id(ipy.user_global_ns)
(user_global_ns
是InteractiveShellEmbed
的超类的类属性,它返回ipy.user_module.__dict__
)id(locals()) == id(ipy.user_ns)
id(locals()) == id(globals())
user_global_ns
(一个属性)和user_ns
(一个字典)定义执行上下文ipy.user_module
和ipy.user_ns
在函数ipy.__call__()
中设置并传递给ipy.mainloop()
。由于ipy.user_ns
是在函数内部构造的,因此它们不是同一对象。如果要在函数外部启动ipython(例如在脚本中),则可以安全地假设globals()
应该与locals()
相同。
使用此设置,在不使用默认嵌入式外壳程序的情况下,以下代码应该可以工作:
a=3
(lambda :a)() # default behavior: name 'a' is not defined
import time
(lambda: time.time())() # default behavior: name 'time' is not defined
(默认行为是由于a
和time
未添加到globals()
中,并且ipython
并未关闭局部函数(上面定义的lambda),并坚持在全局范围内查找变量。搜索closure
in this page)