是否可以从框架对象中检索任何类信息?我知道如何获取文件(frame.f_code.co_filename),函数(frame.f_code.co_name)和行号(frame.f_lineno),但希望能够获取活动对象的类的名称框架的实例(如果不是实例,则为None)。Python:如何从'框架'对象检索类信息?
回答
我不相信,在框架对象级别,有任何方法可以找到已调用的实际python函数对象。
但是,如果你的代码依赖于共同约定:命名方法self
的实例参数,那么你可以做到以下几点:
def get_class_from_frame(fr):
import inspect
args, _, _, value_dict = inspect.getargvalues(fr)
# we check the first parameter for the frame function is
# named 'self'
if len(args) and args[0] == 'self':
# in that case, 'self' will be referenced in value_dict
instance = value_dict.get('self', None)
if instance:
# return its class
return getattr(instance, '__class__', None)
# return None otherwise
return None
如果你不想使用getargvalues
,你可以直接使用frame.f_locals
而不是value_dict
和frame.f_code.co_varnames[:frame.f_code.co_argcount]
而不是args
。
请记住,这仍然只是依靠惯例,所以它是不可移植的,并且容易出错:
- 如果非法功能使用
self
作为第一个参数名称,然后get_class_from_frame
将错误返回第一个参数的类。 - 使用描述符时它可能会引起误解(它将返回描述符的类,而不是被访问的实际实例)。
@classmethod
和@staticmethod
将不会采取self
参数,并与描述符一起实现。- ,肯定有很多更取决于正是你想做的事
,你可能要花费一些时间来深入挖掘,并找到解决方法的所有这些问题(你可以检查框功能存在于返回的类和共享相同的来源,检测描述符调用是可能的,类方法相同等。)
这有点短,但大致相同。如果班级名称不可用,则返回无。
def get_class_name():
f = sys._getframe(1)
try:
class_name = f.f_locals['self'].__class__.__name__
except KeyError:
class_name = None
return class_name
好的答案!更好的是,你可以做''f.f_locals ['__ class __'] .__ name__'',它也应该覆盖''classmethod''和''staticmethod''的情况。 – 2015-01-07 21:38:06
@LucioPaiva不起作用。在f_locals中没有关键的'__class __'。 – Pithikos 2015-05-15 16:01:32
我刚刚遇到这篇文章,因为我遇到了同样的问题。然而,我并没有将“自我”方法视为可接受的解决方案,因为已经列出的所有原因。
下面的代码演示了一种不同的方法:给定一个框架对象,它在全局变量中搜索匹配成员名称和代码块的对象。搜索并不全面,所以有可能不是所有的类都会被发现,但是找到的类应该是我们正在寻找的类,因为我们验证了匹配的代码。代码
对象是在前面加上函数名与它的类名,如发现:
def get_name(frame):
code = frame.f_code
name = code.co_name
for objname, obj in frame.f_globals.iteritems():
try:
assert obj.__dict__[name].func_code is code
except Exception:
pass
else: # obj is the class that defines our method
name = '%s.%s' % (objname, name)
break
return name
注意使用的__dict__
代替getattr
防止派生类的醒目。
还请注意,如果self = frame.f_locals['self']; obj = self.__class__
给出匹配项或任何obj in self.__class__.__bases__
或更深,则可以避免全局搜索,所以确实存在优化/杂交的空间。
如果一个方法是一个类方法,该类将是第一个参数。这将打印出每个调用堆栈帧的第一个arg的类型(如果存在):
def some_method(self):
for f in inspect.getouterframes(inspect.currentframe()):
args, _,_, local_dict = inspect.getargvalues(f[0])
if args:
first_arg = args[0]
first_value = local_dict[first_arg]
print(type(first_value).__name__)
- 1. 从SOAP信封中检索类对象?
- 2. 如何从数据绑定中检索对象属性信息
- 3. 如何从IQueryable对象中检索订购信息?
- 4. 如何从python对象检索值?
- 5. 用Doctrine检索对象信息
- 6. 如何从数组中检索信息
- 7. 如何从$ .post中检索信息
- 8. 如何检索基类(实体框架)?
- 9. 如何检索有关图像对象的信息
- 10. 从ArrayCollection中检索对象物品信息?
- 11. 从OLAP中检索信息
- 12. 从curl检索信息
- 13. 检索从调试信息
- 14. 从非活动类中调用的自定义对话框中检索信息
- 15. 如何从一个类检索信息到另一个
- 16. 实体框架Core从表中检索单个对象
- 17. Python,从类对象中抓取信息不起作用
- 18. Zend框架 - 如何从请求对象
- 19. 从ABRecordRef检索即时消息信息
- 20. 信息架构,如何检索链接表
- 21. Python检索Windows服务信息
- 22. 检索DLL信息
- 23. ADHoc信息检索
- 24. 如何从NSMutableArray中检索对象
- 25. 如何从Go http.Request中检索对象?
- 26. 如何从该对象检索值
- 27. 如何从jlist检索对象列表
- 28. 如何从stdClass对象中检索值?
- 29. 如何从内存中检索对象
- 30. 如何从PHP中检索MySql全文索引信息?
感谢您的回答,Clément;它是详细和周到的。我仍然希望获得不止一个回应!但是,如果没有,这一个将足以... – 2010-02-08 23:32:17
好吧,等待足够长。这是一个很好的答案!我曾希望能从框架结构中获得更好的支持,但事实就是如此。再次感谢克莱门特! – 2010-02-11 23:16:19
要添加一个到列表中,请注意'自己'可能是一个派生类的实例,可能不是我们感兴趣的类。 – gertjan 2013-03-29 13:38:08