Belirli bir modülde verilen bir sınıfının alt sınıflarını üzerinde yineleme

oy
15

Python, ben nasıl yineleme veya modül X mevcut Y, tüm alt sınıflar bir listesini oluşturabilir, bir modül X ve bir sınıf Y verilen?

Oluştur 04/09/2008 saat 17:05
kaynak kullanıcı
Diğer dillerde...                            


4 cevaplar

oy
11

İşte bunu yapmak için tek yolu şudur:

import inspect

def get_subclasses(mod, cls):
    """Yield the classes in module ``mod`` that inherit from ``cls``"""
    for name, obj in inspect.getmembers(mod):
        if hasattr(obj, "__bases__") and cls in obj.__bases__:
            yield obj
Cevap 04/09/2008 saat 17:20
kaynak kullanıcı

oy
1

Modül foo.py Verilen

class foo(object): pass
class bar(foo): pass
class baz(foo): pass

class grar(Exception): pass

def find_subclasses(module, clazz):
    for name in dir(module):
        o = getattr(module, name)

        try: 
             if issubclass(o, clazz):
             yield name, o
        except TypeError: pass

>>> import foo
>>> list(foo.find_subclasses(foo, foo.foo))
[('bar', <class 'foo.bar'>), ('baz', <class 'foo.baz'>), ('foo', <class 'foo.foo'>)]
>>> list(foo.find_subclasses(foo, object))
[('bar', <class 'foo.bar'>), ('baz', <class 'foo.baz'>), ('foo', <class 'foo.foo'>), ('grar', <class 'foo.grar'>)]
>>> list(foo.find_subclasses(foo, Exception))
[('grar', <class 'foo.grar'>)]
Cevap 04/09/2008 saat 17:29
kaynak kullanıcı

oy
4

Chris Atlee ve zacherates gelen cevapların ne gereklerini yerine getirmek olduğunu önerebilir misiniz? Ben zacerates cevap bu değişiklik daha iyi olduğunu düşünüyorum:

def find_subclasses(module, clazz):
    for name in dir(module):
        o = getattr(module, name)
        try:
            if (o != clazz) and issubclass(o, clazz):
                yield name, o
        except TypeError: pass

Bana verilen cevaplar katılmıyorum nedeni ilk verilen sınıfın uzak bir alt sınıfıdır sınıfları üretmek olmadığını, ikincisi verilen sınıf içerir.

Cevap 05/09/2008 saat 21:54
kaynak kullanıcı

oy
20

Quamrana önerisi çalışıyor olsa da, ben daha pythonic yapmak önermek istiyorum olası iyileştirmeler bir çift vardır. Bunlar, standart kütüphanesinden kontrol modülünü kullanarak dayanır.

  1. Sen kullanarak getattr çağrıyı önleyebilirsiniz inspect.getmembers()
  2. deneme / yakalama kullanılarak önlenebilir inspect.isclass()

İstersen o ile, tek bir liste anlama Tüm olayı azaltabilir:

def find_subclasses(module, clazz):
    return [
        cls
            for name, cls in inspect.getmembers(module)
                if inspect.isclass(cls) and issubclass(cls, clazz)
    ]
Cevap 03/01/2009 saat 00:56
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more