質問

So I have a .py file containing a class where its subclasses can be accessed as properties. All these subclasses are defined beforehand. I also need all the subclasses to have the same ability (having their own subclasses be accessible as properties). The biggest problem I've been facing is that I don't know how to access the current class within my implementation of __getattr__(), so that'd be a good place to start.

Here's some Python+Pseudocode with what I've tried so far. I'm pretty sure it won't work since __getattr__() seems to be only working with instances of a class. If that is case, sorry, I am not as familiar with OOP in Python as I would like.

class A(object):
    def __getattr__(self, name):
        subclasses = [c.__name__ for c in current_class.__subclasses__()]
        if name in subclasses:
            return name
    raise AttributeError
役に立ちましたか?

解決

If I've understood your question properly, you can do what you want by using a custom metaclass that adds a classmethod to its instances. Here's an example:

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'

For something that works in both Python 2 and 3, define the class as shown below. Derives Base from a class that has SubclassAttributes as its metaclass. The is similar to what the six module's with_metaclass() function does:

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

他のヒント

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

Out of curiosity, what is this designed to be used for?

>>> class A(object):
...     pass
...
>>> foo = A()
>>> foo.__class__
<class '__main__.A'>
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top