如何作为属性访问类的子类?

时间:2012-08-08 03:40:13

标签: python class properties getattr

所以我有一个.py文件,其中包含一个类,其子类可以作为属性进行访问。所有这些子类都是事先定义的。我还需要所有子类具有相同的能力(将自己的子类作为属性访问)。我遇到的最大问题是我不知道如何在__getattr__()的实现中访问当前的类,所以这是一个很好的起点。

这是我迄今为止尝试过的一些Python + Pseudocode。我很确定它不起作用,因为__getattr__()似乎只适用于类的实例。如果是这种情况,抱歉,我对Python中的OOP并不熟悉。

class A(object):
    def __getattr__(self, name):
        subclasses = [c.__name__ for c in current_class.__subclasses__()]
        if name in subclasses:
            return name
    raise AttributeError

3 个答案:

答案 0 :(得分:2)

    class A(object):
        def __getattr__(self, key):
            for subclass in self.__class__.__subclasses__():
                if (subclass.__name__ == key):
                    return subclass
            raise AttributeError, key

出于好奇,这个设计用于什么?

答案 1 :(得分:2)

如果我已正确理解您的问题,您可以使用向其实例添加classmethod的自定义元类来执行您想要的操作。这是一个例子:

class SubclassAttributes(type):
    def __getattr__(cls, name):  # classmethod of instances
        for subclass in cls.__subclasses__():
            if subclass.__name__ == name:
                return subclass
        else:
            raise TypeError('Class {!r} has no subclass '
                            'named {!r}'.format(cls.__name__, name))

class Base(object):
    __metaclass__ = SubclassAttributes  # Python 2 metaclass syntax

#class Base(object, metaclass=SubclassAttributes):  # Python 3 metaclass syntax
#    """ nothing to see here """

class Derived1(Base): pass
class Derived2(Base): pass

print(Base.Derived1)  # -> <class '__main__.Derived1'>
print(Base.Derived2)  # -> <class '__main__.Derived2'>
print(Base.Derived3)  # -> TypeError: Class 'Base' has no subclass named 'Derived3'

对于适用于Python 2和3的内容,请按如下所示定义类。从具有SubclassAttributes作为其元类的类派生Base。这类似于six模块的with_metaclass()函数所做的事情:

class Base(type.__new__(type('TemporaryMeta', (SubclassAttributes,), {}),
                        'TemporaryClass', (), {})): pass

答案 2 :(得分:1)

>>> class A(object):
...     pass
...
>>> foo = A()
>>> foo.__class__
<class '__main__.A'>