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'>)
精彩评论