在尝试使用内省通过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访问。有人可以解释一下吗?
有没有办法从字符串生成一个类,即使该类只在非全局范围内?
答案 0 :(得分:2)
在函数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
,属性type("LocalClass", (object,), {"foo": "bar"})
设置为&#34; bar&#34;通过执行globals()["LocalClass"] = ...
并在变量中捕获返回的类。您可以通过执行import __main__
PS:通过LocalClass.__module__
更简单(不确定,更漂亮)获取主模块的方法。这可以在任何模块中使用,但我通常建议不要使用它,除非你知道你在做什么,因为一般来说,python人不喜欢你做这种事情。
编辑:在查看链接的问题之后,您不想动态创建新类,而是根据它的名称检索变量。链接问题中的所有答案都会这样做。我会让你决定你最喜欢哪一个
EDIT2:__main__
与Foo
相同,因为那是您定义类的模块。如果您在__main__
导入的模块__module__
中定义了它(并且实际上并非单独运行),您会发现LocalClass
将是&#34; B&#34;。即使在__main__
中定义dir
,它也不会因为它是一个类而自动进入全局表 - 在python中,你可能已经知道了,(几乎)一切都是一个东西。 __dict__
函数搜索范围中定义的所有变量。当您在主要范围内查看时,它几乎等同于执行globals()
或LocalClass
但略有不同。因为locals()
是本地的,所以它不是在全局上下文中定义的。如果您在功能f
内进行了LocalClass
,则会发现$this->db->select("initiation.*, project.projectname,subproject.subprojectname, concat(employee.firstname,' ',employee.lastname) as 'name'")
->from('initiation')
->join('project','initiation.projectid=project.id')
->join('employee','initiation.leaderid = employee.id')
->join('subproject','initiation.subprojectid=subproject.id','left');
$query = $this->db->get();
$result = $query->result_array();//changed
return $result;//changed
会出现在该列表中