有没有办法删除Python中的嵌套类?

有没有办法删除Python中的嵌套类?,python,metaprogramming,Python,Metaprogramming,下面的脚本试图从类Outer中删除Inner1嵌套类。我得到一个明确的错误“TypeError:无法删除_类_属性”。死胡同 def Loader(cls): for key in dir(cls): value = getattr(cls, key) if isinstance(value, type): delattr(cls, key) return cls @Loader class Outer: clas

下面的脚本试图从类
Outer
中删除
Inner1
嵌套类。我得到一个明确的错误“TypeError:无法删除_类_属性”。死胡同

def Loader(cls):
    for key in dir(cls):
        value = getattr(cls, key)
        if isinstance(value, type):
            delattr(cls, key)
    return cls

@Loader
class Outer:
    class Inner1:
        X = 1

print(Outer.Inner1.X)

问题在于以下行:

if isinstance(value, type):
正在匹配从
类型继承的所有内容。如果只希望删除在修饰类中显式定义的内部类,可以使用以下方法:

from inspect import isclass

def Loader(cls):
    # vars returns the __dict__ attributes, so only names that are explicitely defined in cls.
    for key, value in vars(cls).copy().items():

        # If it is a class, delete it
        if isclass(value):
            delattr(cls, key)

    return cls

@Loader
class Outer:
    class Inner1:
        X = 1

print(Outer.Inner1.X) # AttributeError: type object 'Outer' has no attribute 'Inner1'
另一种方法是将您的decorator设置为类,并明确告诉它您要删除的名称。例如

class Loader:
    def __init__(self, *args):
        # Store the given names to delete
        self.names = args

    def __call__(self, cls):
        for name in self.names:
            try:
                delattr(cls, name)
            except AttributeError:
                pass

        return cls

@Loader('Inner1', 'Inner2', 'etc')
class Outer:
    class Inner1:
        X = 1

print(Outer.Inner1.X) # AttributeError: type object 'Outer' has no attribute 'Inner1'

也就是说,我不知道为什么要装饰一个类并定义要动态删除的内部类。。。为什么不呢?只是根本不定义它们D

记住
\uuuu dir\uuuu
返回所有类型的东西。将其简化为
delattr(外部,'Inner1')
将按预期工作-所发生的是
dir(cls)
生成了
\uu class\uuuuuu
属性,该属性不能从任何类中删除,因为生成了
delattr(外部,'uu class\uuuu'))
Loader
尝试删除的不仅仅是
Inner1
,它还尝试删除
cls
中属于
类型的实例的任何内容。这个错误其实很明显-你的代码试图删除
\uuuu class\uuuu
属性,但它不能。“我不确定你为什么要装饰一个类并定义你将动态删除的内部类…为什么不…只是根本不定义它们?”问得好。我能想象的唯一原因是,如果出于某种教学原因,我想禁止使用特定功能(如嵌套类),学生作业的自动评分。在这种情况下,我想知道是否使用了嵌套类,而不是删除它,但在其他类似的模糊用例中,删除嵌套类可能是正确的做法。