栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

嵌套函数是否存在等效的替代?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

嵌套函数是否存在等效的替代?

这是一种实现方法,它是通过侵入函数内部来创建一个“做正确的事”的新foo。(如@DSM所述)。不幸的是,我们不能直接进入

foo
函数并弄乱它的内部,因为它们大多被标记为只读,因此我们要做的就是手动修改一个副本。

# Here's the original functiondef foo():  def bar():    print("    In bar orig")  def baz():    print("  Calling bar from baz")    bar()  print("Foo calling bar:")  bar()  print("Foo calling baz:")  baz()# Here's using itfoo()# Now lets override the bar functionimport types# This is our replacement functiondef my_bar():  print("   Woo hoo I'm the bar override")# This creates a new pre object used by our new foo function # based on the old foo functions pre object.foopre = types.CodeType(    foo.func_pre.co_argcount,    foo.func_pre.co_nlocals,    foo.func_pre.co_stacksize,    foo.func_pre.co_flags,    foo.func_pre.co_pre,    # This tuple is a new version of foo.func_pre.co_consts    # NOTE: Don't get this wrong or you will crash python.    (        foo.func_pre.co_consts[0],       my_bar.func_pre,       foo.func_pre.co_consts[2],       foo.func_pre.co_consts[3],       foo.func_pre.co_consts[4]    ),    foo.func_pre.co_names,    foo.func_pre.co_varnames,    foo.func_pre.co_filename,    foo.func_pre.co_name,    foo.func_pre.co_firstlineno,    foo.func_pre.co_lnotab,    foo.func_pre.co_freevars,    foo.func_pre.co_cellvars )# This is the new function we're replacing foo with# using our new pre.foo = types.FunctionType( foopre , {})# Now use itfoo()

我很确定它不会涵盖所有情况。但这适用于示例(对我而言,在旧的python 2.5.1上)

可能会整理一些丑陋的地方是:

  1. 庞大的参数列表传递给CodeType
  2. co_consts
    仅覆盖一个成员构成的丑陋的元组。所有信息都在co_consts中以确定要替换的内容-因此,更智能的功能可以做到这一点。我用手工挖了内部零件
    print( foo.func_pre.co_consts )

您可以使用解释器命令找到有关

CodeType
FunctionType
的信息
help( types.CodeType )

更新:我认为这太难看了,所以我建立了一个辅助函数使其更漂亮。使用帮助程序,您可以编写:

# Use our function to get a new version of foo with "bar" replaced by mybar    foo = monkey_patch_fn( foo, "bar", my_bar )# Check it worksfoo()

这是实现

monkey_patch_fn

# Returns a copy of original_fn with its internal function# called name replaced with new_fn.def monkey_patch_fn( original_fn, name, new_fn ):  #Little helper function to pick out the correct constant  def fix_consts(x):    if x==None: return None    try:      if x.co_name == name:        return new_fn.func_pre    except AttributeError, e:        pass    return x  original_pre = original_fn.func_pre  new_consts = tuple( map( fix_consts, original_pre.co_consts ) )  pre_type_args = [     "co_argcount", "co_nlocals", "co_stacksize", "co_flags", "co_pre",     "co_consts", "co_names", "co_varnames", "co_filename", "co_name",     "co_firstlineno", "co_lnotab", "co_freevars", "co_cellvars" ]  new_pre = types.CodeType(     *[ ( getattr(original_pre,x) if x!="co_consts" else new_consts )        for x in pre_type_args ] )  return types.FunctionType( new_pre, {} )


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/646949.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号