2009-11-20 101 views
1

有沒有辦法標記類聲明,以便稍後您可以獲取標記的列表?Python中特定類名稱的列表

或者讓一個字符串開始的所有類的方法嗎?

或所有類是特定類的子類?

+0

使用'grep'搜索源代碼有什麼問題?你有所有Python的源代碼。爲什麼不能在這些文件上簡單地使用'grep'? – 2009-11-20 15:56:49

回答

3

注意:在下面我假設Python 3.x.對於Python 2.x,請使用new style classes,即編寫class T(object): pass而不是class T: pass

  1. 首先,定義一些類:

    >>> class T: pass 
    ... 
    >>> class S: pass 
    ... 
    >>> class U(T): pass 
    ... 
    
  2. 要獲得的在當前範圍內定義的類的列表,遍歷globals(或locals)和測試他們是否是type實例使用isinstance(因此一個類!):

    >>> [n for n, o in globals().items() if isinstance(o, type)] 
    ['S', 'U', 'T'] 
    
  3. 使用issubclassŧ Ø限制你搜索到給定類的子類(在這種情況下T):

    >>> [n for n, o in globals().items() if isinstance(o, type) and issubclass(o, (T,))] 
    ['U', 'T'] 
    
  4. 你可能想省略T本身:

    >>> [n for n, o in globals().items() if o != T and isinstance(o, type) and issubclass(o, (T,))] 
    ['U'] 
    
  5. 要獲得所有課程開始具有一定的字符串,調用startswith在類名:

    >>> [n for n, o in globals().items() if n.startswith('T') and isinstance(o, type)] 
    ['T'] 
    
  6. 標誌創建時某些職業,使用class decorator†添加屬性,例如__flagged__

    >>> def flag(cls): 
    ...  cls.__flag__ = 'flagged' 
    ...  return cls 
    ... 
    >>> @flag 
    ... class X: pass 
    ... 
    >>> @flag 
    ... class Y: pass 
    ... 
    >>> class Z: pass 
    ... 
    
  7. 現在,你可以只選擇那些與__flag__屬性歸類:

    >>> [n for n, o in globals().items() if isinstance(o, type) and hasattr(o, '__flag__')] 
    ['X', 'Y'] 
    

    &匕首;:由於bobince筆記,類裝飾器是new in Python 2.6

+0

bobince:是的,它只是在我看來,它不能在2.x工作,因爲我忘了使用新的風格類... – Stephan202 2009-11-20 14:51:10

+0

這一切都看起來很好的Python 2.x ...類裝飾器是新的2.6。 – bobince 2009-11-20 14:53:10

+0

哈,現在看起來我看到了未來,並知道你要評論;) – Stephan202 2009-11-20 14:54:39

1

您還可以使用元類收集起來的類,因爲它們的定義:

class AllSeeingMetaClass(type): 
    # This will be a list of all the classes that use us as a metaclass. 
    the_classes = [] 

    def __new__(meta, classname, bases, classDict): 
     # Invoked as new classes are defined. 
     print "Defining %r" % classname 
     new_class = type.__new__(meta, classname, bases, classDict) 
     meta.the_classes.append(new_class) 
     return new_class 


class MyBase(object): 
    # A base class that pulls in our metaclass. 
    __metaclass__ = AllSeeingMetaClass 


class Cat(MyBase): 
    def __init__(self): 
     pass 

class Dog(MyBase): 
    def __init__(self): 
     pass 

print AllSeeingMetaClass.the_classes 

打印:

Defining 'MyBase' 
Defining 'Cat' 
Defining 'Dog' 
[<class '__main__.MyBase'>, <class '__main__.Cat'>, <class '__main__.Dog'>] 
1

要想從自身內部的類的子類的列表,請使用來自父類的__subclasses__方法。

>>>class Parent(object): 
... pass 
... 
>>>class Child(Parent): 
... pass 
... 
>>>Parent.__subclasses__() 
>>>[<class '__main__.Child'>] 

不幸的是,這方法的文檔很少。