4

以下代码

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

如何让它按照代码中定义这些类的顺序输出?IE

D
C

除了使用 inspect.getsource(A) 并解析之外,还有其他方法吗?

4

6 回答 6

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)

于 2009-03-12T21:51:30.053 回答
5

不,您无法按照您要查找的顺序获取这些属性。Python 属性存储在 dict(读取:hashmap)中,它不知道插入顺序。

另外,我会通过简单地说来避免使用 eval

if type(getattr(A, d)) is types.ClassType:
    print d

在你的循环中。请注意,您也可以只遍历键/值对A.__dict__

于 2009-03-12T21:14:07.960 回答
4

inspect模块也具有该findsource功能。它返回定义对象的源行和行号的元组。

>>> import inspect
>>> import StringIO
>>> inspect.findsource(StringIO.StringIO)[1]
41
>>>

findsource函数实际上搜索源文件并在给定类对象的情况下寻找可能的候选者。

给定一个方法、函数、回溯、框架或代码对象,它只查看co_firstlineno(包含的)代码对象的属性。

于 2009-03-12T22:03:07.903 回答
1

AFAIK,不 - 没有*。这是因为类的所有属性都存储在字典中(如您所知,字典是无序的)。

*:这实际上可能是可能的,但这需要装饰器或可能的元类黑客攻击。你对其中任何一个感兴趣吗?

于 2009-03-12T21:13:00.193 回答
1
class ExampleObject:
    def example2():
        pass
    
    def example1():
        pass

context = ExampleObject

def sort_key(item):
    return inspect.findsource(item)[1]

properties = [
    getattr(context, attribute) for attribute in dir(context)
    if callable(getattr(context, attribute)) and 
    attribute.startswith('__') is False
]
properties.sort(key=sort_key)

print(properties)

应该打印出来:

[<function ExampleObject.example2 at 0x7fc2baf9e940>, <function ExampleObject.example1 at 0x7fc2bae5e790>]

我也需要将它用于我正在构建的一些编译器,这被证明非常有用。

于 2021-12-18T03:41:05.317 回答
0

我不是想在这里流利,但是您可以按字母顺序组织源代码中的课程吗?我发现当一个文件中有很多类时,这本身就很有用。

于 2009-03-12T21:33:47.663 回答