以下代码
import types
class A:
class D:
pass
class C:
pass
for d in dir(A):
if type(eval('A.'+d)) is types.ClassType:
print d
输出
C
D
如何按照代码中定义这些类的顺序输出?即。
D
C
除了使用inspect.getsource(A)并解析之外,还有其他方法吗?
答案 0 :(得分:8)
请注意,在检查中已经为您完成了解析 - 查看inspect.findsource
,它在模块中搜索类定义并返回源和行号。对该行号进行排序(您可能还需要拆分在单独模块中定义的类)应该给出正确的顺序。
但是,这个函数似乎没有记录,只是使用正则表达式来查找行,所以它可能不太可靠。
另一种选择是使用元类或其他方式来隐式或显式地向对象排序信息。例如:
import itertools, operator
next_id = itertools.count().next
class OrderedMeta(type):
def __init__(cls, name, bases, dct):
super(OrderedMeta, cls).__init__(name, bases, dct)
cls._order = next_id()
# Set the default metaclass
__metaclass__ = OrderedMeta
class A:
class D:
pass
class C:
pass
print sorted([cls for cls in [getattr(A, name) for name in dir(A)]
if isinstance(cls, OrderedMeta)], key=operator.attrgetter("_order"))
然而,这是一个相当干扰的变化(需要将您感兴趣的任何类的元类设置为OrderedMeta)
答案 1 :(得分:5)
不,您无法按照您要查找的顺序获取这些属性。 Python属性存储在dict(read:hashmap)中,它不知道插入顺序。
另外,我会通过简单地说
来避免使用evalif type(getattr(A, d)) is types.ClassType:
print d
你的循环中的。请注意,您也可以只遍历A.__dict__
答案 2 :(得分:4)
inspect
模块还具有findsource
功能。它返回一个源元组和行号的元组,其中定义了对象。
>>> import inspect
>>> import StringIO
>>> inspect.findsource(StringIO.StringIO)[1]
41
>>>
findsource
函数实际上会搜索源文件,并在给定类对象的情况下查找可能的候选对象。
给定方法,函数,跟踪,帧或代码对象,它只是查看(包含的)代码对象的co_firstlineno
属性。
答案 3 :(得分:1)
AFAIK,不 - 没有*。这是因为所有类的属性都存储在字典中(如您所知,无序)。
*:它实际上可能是可能的,但这需要装饰器或可能需要元类黑客攻击。你们感兴趣吗?
答案 4 :(得分:0)
我不是想在这里搞笑,但你是否可以按字母顺序组织源中的类?我发现当一个文件中有很多类时,这本身就很有用。