当我试图通过Convert string to Python class object?中的一些建议使用内省从字符串导航到类时,我注意到给定的方法无法在函数的局部作用域中找到类。考虑下面的代码:
import sys
def f():
class LocalClass:
pass
print LocalClass
print 'LocalClass' in dir(sys.modules[__name__])
它给出了输出
__main__.LocalClass
False
我有点困惑,为什么根据类对象本身,LocalClass似乎属于主模块,但无法通过sys.modules访问。有人能解释一下吗
有没有办法从字符串生成类,即使该类仅在非全局范围内
在函数
f
中,LocalClass
确实是局部的。您可以通过尝试__main__.LocalClass
并看到AttributeError: 'module' object has no attribute 'LocalClass'
被引发来看到这一点至于类返回
__main__.LocalClass
的原因,是因为默认情况下,__repr__
函数返回<cls.__module__>.<cls.__name__>
dir
找不到它的原因是因为它只查看在其作用域中定义的变量LocalClass
是本地的,因此如果您查看主模块,它将不会显示从字符串创建类的方法有很多种
第一个也是最容易理解的方法是使用
exec
。现在你不应该只使用exec
来处理随机的事情,这样我就不会使用这个方法了第二种方法是使用
type
函数。它的帮助页面返回type(name, bases, dict)
。这意味着您可以创建一个名为LocalClass
的类,子类为object
,属性foo
设置为“bar”,方法是执行type("LocalClass", (object,), {"foo": "bar"})
并在变量中捕获返回的类。您可以通过执行globals()["LocalClass"] = ...
使类成为全局类PS:获取主模块的一种更简单(不确定是否更漂亮)的方法是执行
import __main__
。这可以在任何模块中使用,但我通常建议不要使用它,除非您知道自己在做什么,因为一般来说,python人员不喜欢您做这种事情编辑:查看链接问题后,您不希望动态创建新类,而是希望检索给定名称的变量。链接问题中的所有答案都可以做到这一点。我让你自己决定你最喜欢哪一个
EDIT2:
LocalClass.__module__
与__main__
相同,因为这是您定义该类的模块。如果您在由__main__
导入的模块Foo
中定义了它(实际上并不是独立运行的),您会发现__module__
将是“B”。尽管LocalClass
是在__main__
中定义的,但它不会自动进入全局表,因为它是一个类——在python中,正如您可能已经知道的那样,(几乎)一切都是一个对象。dir
函数搜索范围中定义的所有变量。正如您在主范围中所看到的,它几乎等同于执行__dict__
或globals()
,但有一些细微的区别。因为LocalClass
是本地的,所以它没有在全局上下文中定义。但是,如果在函数f
内执行locals()
,您会发现LocalClass
将出现在该列表中相关问题 更多 >
编程相关推荐