我有一个函数可以创建从它的参数派生的类:
def factory(BaseClass) :
class NewClass(BaseClass) : pass
return NewClass
现在,当我使用它来创建新类时,这些类的名称都相同,并且实例看起来像它们具有相同的类型:
NewA = factory(ClassA)
NewB = factory(ClassB)
print type(NewA()) # <class __main__.NewClass>
print type(NewB()) # <class __main__.NewClass>
是否需要手动设置__name__
属性?
NewA.__name__ = 'NewA'
print type(NewA()) # <class __main__.NewA>
当我在这里时,我还应该设置其他任何东西吗?
答案 0 :(得分:42)
是的,设置__name__
是正确的做法;你不需要设置任何其他东西来调整类名。
例如:
def factory(BaseClass) :
class NewClass(BaseClass): pass
NewClass.__name__ = "factory_%s" % BaseClass.__name__
return NewClass
type
是错误的在这里使用的东西。它不允许您使用Python's normal class syntax定义类,而是让您手动设置每个类属性。它用于手动创建类,例如如果你有一个基类数组,并且你想用它创建一个类(你不能用Python的类语法)。不要在这里使用它。
答案 1 :(得分:13)
使用带有三个参数的type()
函数进行检查。以下代码创建了一个新类“NewA”,其中object
为基本类型,没有初始属性。
>>> type('NewA', (object,), {})
<class '__main__.NewA'>
答案 2 :(得分:3)
更新Glenn Maynard的答案:如今有__name__
属性和__qualname__
属性。首先是您可能会想到的;第二个是嵌套类的点缀“路径”。
如果是“简单”类,则两者相等。只需将__name__
和__qualname__
设置为您的新名称。您应该同时设置两个属性,因为不能确定将显示哪个第三方代码。
现在,对于嵌套类,两个属性之间的差异显示:
class Outer:
class Inner:
pass
print(Outer.__name__, Outer.__qualname__)
print(Outer.Inner.__name__, Outer.Inner.__qualname__)
打印:
Outer Outer
Inner Outer.Inner
如果要更改Outer
的名称,则需要打3个位置,即Outer.__name__
,Outer.__qualname__
,Inner.__qualname__
。对于后两个,您需要正确分割并连接点。
最后的警告:即使您做了所有正确的操作,狮身人面像,皮林特等东西仍可能无法100%正常工作。例如,不能像往常一样在模块名称空间中找到虚假名称。无法为类定义grep
填充源;等等。