如何动态设置类名?

kiy*_*iyo 41 python

我有一个函数创建从它的参数派生的类:

def factory(BaseClass) :
    class NewClass(BaseClass) : pass
    return NewClass
Run Code Online (Sandbox Code Playgroud)

现在,当我使用它来创建新类时,这些类的名称都相同,并且实例看起来像它们具有相同的类型:

NewA = factory(ClassA)
NewB = factory(ClassB)
print type(NewA()) # <class __main__.NewClass>
print type(NewB()) # <class __main__.NewClass>
Run Code Online (Sandbox Code Playgroud)

是否正确修复了手动设置__name__属性?

NewA.__name__ = 'NewA'
print type(NewA()) # <class __main__.NewA>
Run Code Online (Sandbox Code Playgroud)

我在做什么时还应该设置其他东西吗?

Gle*_*ard 43

是的,设置__name__是正确的做法; 你不需要设置其他任何东西来调整类名.

例如:

def factory(BaseClass) :
    class NewClass(BaseClass): pass
    NewClass.__name__ = "factory_%s" % BaseClass.__name__
    return NewClass
Run Code Online (Sandbox Code Playgroud)

type在这里使用是错误的.它不允许您使用Python的普通类语法定义类,而是让您手动设置每个类属性.它用于手动创建类,例如,如果你有一个基类数组,并且你想用它创建一个类(你不能用Python的类语法).不要在这里使用它.

  • 不再正确,现在你还需要改变__qualname__.请参阅https://www.python.org/dev/peps/pep-3155/ (7认同)

Mar*_*eth 14

使用type()带有三个参数的函数检出.以下代码创建一个新类"NewA",object作为基类型,没有初始属性.

>>> type('NewA', (object,), {})
<class '__main__.NewA'>
Run Code Online (Sandbox Code Playgroud)


Tor*_*ein 5

更新Glenn Maynard的答案:现在有__name__属性和__qualname__属性。首先是您可能会想到的;第二个是嵌套类的虚线“路径”。

如果是“简单”类,则两者是相等的。只需设置__name____qualname__使用您的新名称即可。您应该同时设置这两个属性,因为不能确定将显示哪个第三方代码。

现在,对于嵌套类,两个属性之间的差异如下所示:

class Outer:
    class Inner:
        pass
print(Outer.__name__, Outer.__qualname__)
print(Outer.Inner.__name__, Outer.Inner.__qualname__)
Run Code Online (Sandbox Code Playgroud)

印刷品:

Outer Outer
Inner Outer.Inner
Run Code Online (Sandbox Code Playgroud)

如果你想改变Outer的名字,你需要修补三个地方,分别是Outer.__name__Outer.__qualname__Inner.__qualname__。对于后两个,您需要正确分割并连接点。

最后的警告:即使您做了所有正确的操作,狮身人面像,皮林特等东西仍可能无法100%起作用。例如,不能像往常一样在模块名称空间中找到虚假名称。无法grep为类定义对源进行搜索;等等。

  • 我发现我还必须更改“__module__”才能完全模拟类名。 (3认同)