开发者

Python: How can I subclass a class I'm nesting in?

I am trying to do the following in a bit of python code:

class Parent:
    class Child(Parent):
        pass

An开发者_高级运维d it does not work. Is there any python syntax I can use to achieve the same result?

Thanks.


You can't do that because at the point where Child is being defined, Parent is not defined yet (definition in progress). Nested classes are not usually used in Python, you can just declare different classes in the same module. However, if you absolutely need to achieve the outlined setup, you can do this:

class Parent: pass
class Child (Parent): pass

Parent.Child = Child
del Child


Inner classes have no special relationship with their outer classes in Python, so there's really no reason to use them. Also, having a class as a class attribute of another class is not usually an optimal design. By restructuring a bit, I bet you could come up with a solution that doesn't require or desire this behavior and that is better and more idiomatic.


I strongly recommend against doing anything like the following; there really isn't any reason I can think of to do it, and it's overly complicated. But for educational purposes...

It is possible to have a metaclass (or a class decorator, I suppose) replace some object that came from a class definition with an actual subclass, after the enclosing (Parent) class has been created.

For example in the following, we check for the presence of a special marker (a class called ReplaceMe) in the __bases__ attribute of each of our class attributes. If we find it, we assume that what we found was a stand in for what is supposed to be a subclass. We make a new (sub-)class dynamically, replacing the ReplaceMe class with ourself.

class ReplaceMe(object): pass

class DerivedInnerChildren(type):
    def __init__(cls, name, bases, attrs):
        for k, v in attrs.items():
            if ReplaceMe in getattr(v, '__bases__', ()):
                child_name = v.__name__
                child_bases = tuple([
                    base if base is not ReplaceMe else cls
                    for base in v.__bases__])
                child_attrs = dict(v.__dict__)
                setattr(cls, k, type(child_name, child_bases, child_attrs))

class Parent(object):
    __metaclass__ = DerivedInnerChildren
    class Child(ReplaceMe): 
        pass

print Parent
print Parent.Child
print 'Parent in Child mro?', Parent in Parent.Child.__mro__
print Parent.Child.__mro__

This prints:

<class '__main__.Parent'>
<class '__main__.Child'>
Parent in Child mro? True
(<class '__main__.Child'>, <class '__main__.Parent'>, <type 'object'>)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜