Python:`locals()`作为默认函数参数

时间:2018-07-29 03:18:41

标签: python python-2.7

假设我有一个具有功能PyFoo.py的模块bar。我希望bar打印与调用它的名称空间关联的所有局部变量。

例如:

#! /usr/bin/env python
import PyFoo as pf
var1 = 'hi'
print locals()
pf.bar()

最后两行将提供相同的输出。到目前为止,我已经尝试过这样定义bar

def bar(x=locals):
    print x()

def bar(x=locals()):
    print x

但是都行不通。第一个结局是bar命名空间的本地内容(我猜是因为那是在评估时),第二个就像我传入了globals(我认为是因为它被评估了)在import期间)。

有没有办法让x的参数bar的默认值成为命名空间bar中的所有变量?

编辑2018-07-29:

正如已经指出的,给出的是一个XY问题。这样,我会详细说明。

我正在组合的模块将允许用户创建代表数值问题不同方面的各种对象(例如各种拓扑定义,边界条件,本构模型等),并定义任何给定对象如何与任何对象交互其他对象。这个想法是让用户导入模块,定义他们需要的各种模型实体,然后调用一个函数,该函数将接受传递给它的所有对象,进行必要的调整以确保它们之间的功能,然后写出一个文件用文本文件表示整个数值问题。

模块具有函数generate,该函数接受数值问题的各个方面。所有参数的默认值是一个空列表。如果传递了非空列表,则generate将使用这些实例来生成完整的数值问题。如果参数是一个空列表,那么我希望它接受名为generate的命名空间中的所有实例(然后我将解析出该参数的适当实例)。

编辑2018-07-29:

很抱歉,我缺乏理解(我不是一个程序员那样强),但是我想我可能了解您对实例的声明或声明的意思。已注册。

根据我的有限理解,可以通过在导入模块时创建的模块中创建某种注册表数据集(例如listdict)来完成此操作,默认情况下,模块类接受此注册表对象。在类初始化期间,self可以附加到所述数据集,然后genereate函数将注册表作为参数之一的默认值?

1 个答案:

答案 0 :(得分:1)

您无法直接做自己想做的事。

locals只是在调用它的任何名称空间中返回局部变量。如您所见,您可以访问在定义函数时在其中定义函数的名称空间,并且可以访问该名称空间功能本身,但您无权访问任何其他名称空间。

可以间接进行 想要的工作……但这几乎肯定是一个坏主意。至少这闻起来像XY problem的味道,无论您实际上想做什么,都有可能是一种更好的方法。

但是偶尔还是有必要的,所以如果您遇到以下情况之一:


要了解呼叫者的本地信息的主要原因是进行某种调试或其他自省功能。进行内省的方法几乎总是通过inspect库。

在这种情况下,您要检查的是the interpreter call stack。调用函数将是调用堆栈中位于函数自身框架之后的第一帧。

您可以获得原始堆栈帧:

inspect.currentframe().f_back

…或您可以得到代表它的FrameInfo

inspect.stack()[1]

inspect文档顶部所述,框架对象的本地名称空间可用于:

frame.f_locals

请注意,这与适用于使用locals获取自己的本地人的所有警告相同:获得的不是实时名称空间,但是即使可变的映射也不能用于修改名称空间(或更糟糕的是,在2.x版本中,可能会或可能不会修改名称空间),并且所有单元格和自由变量都扁平化为它们的值而不是它们的单元格参考。

此外,请参阅文档中的大警告:不要使框架对象不必要地保持活动状态(或者,如果您需要保留快照而不是所有引用,则调用其clear方法,但我认为仅存在于3.x)。