Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何动态设置类名?_Python - Fatal编程技术网

Python 如何动态设置类名?

Python 如何动态设置类名?,python,Python,我有一个函数,可以创建从其参数派生的类: def factory(BaseClass) : class NewClass(BaseClass) : pass return NewClass 现在,当我使用它创建新类时,这些类的名称都是相同的,实例的类型看起来也一样: NewA = factory(ClassA) NewB = factory(ClassB) print type(NewA()) # <class __main__.NewClass> print ty

我有一个函数,可以创建从其参数派生的类:

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>
当我进行设置时,是否还有其他需要设置的内容?

使用带有三个参数的函数进行检查。下面的代码创建了一个新类“NewA”,其基本类型为
object
,没有初始属性

>>> type('NewA', (object,), {})
<class '__main__.NewA'>
>>类型('NewA',(对象,),{})

是的,设置
\uuuu name\uuuu
是正确的做法;您不需要设置任何其他内容来调整类名

例如:

def factory(BaseClass) :
    class NewClass(BaseClass): pass
    NewClass.__name__ = "factory_%s" % BaseClass.__name__
    return NewClass

类型
在这里使用是错误的。它不允许您使用定义类,而是让您手动设置每个类属性。它用于手动创建类,例如,如果您有一个基类数组,并且希望使用它创建一个类(这是Python的类语法无法做到的)。不要在这里使用它。

更新格伦·梅纳德的答案:现在有了
\uuuuuu name\uuuuuuu
属性和
\uuuu qualname\uuuuu
属性。第一个是你的想法;第二个是嵌套类的虚线“路径”

在“简单”类的情况下,两者是相等的。只需将
\uuuu name\uuuuu
\uuuu qualname\uuuu
设置为您的新名称。您应该设置这两个属性,因为您无法确定第三方代码将查看哪一个

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

class Outer:
    class Inner:
        pass
print(Outer.__name__, Outer.__qualname__)
print(Outer.Inner.__name__, Outer.Inner.__qualname__)
印刷品:

Outer Outer
Inner Outer.Inner
如果您想更改
外部
的名称,您需要修补三个位置,即
外部。\uuuuu name\uuuuuuu
外部。\uuuuuuuu质量名称
内部。\uuuuuu质量名称
。对于后两种情况,您需要在点处正确拆分和连接


最后一个警告:即使你做得很好,像斯芬克斯,派林,等等。。。可能仍然无法100%工作。例如,像往常一样,在模块名称空间中找不到假名称;类定义的源不能是
grep
ped;等等。

如果NewClass中的类定义很长,则看起来有点笨拙。我必须将所有方法累加到一个字典中(我假设doc字符串也在那里,在键
“\uu doc\uu”
下)。另外,如果NewClass中的方法必须动态引用基类的方法,该怎么办?
type
用于创建具有可变基列表的类;这完全是一个错误的工具。@kiyo:在您的示例代码中,NewClass除了名称和基类之外没有定义任何东西,所以这个方法可以很好地工作。如果您的新类将在其中包含实际属性,那么是的,更改
\uuuuu name\uuuuu
是很好的选择。但是,这两个方法的功能都一样好。如果访问由type()创建的类,则会出现NameError。我该怎么解决呢?不再正确了,现在你还需要更改qualname。请看@TorbenKlein我们现在需要同时设置
\uuuuuqualname\uuu
\uuuu name\uuuu
还是只设置
\uuuuqualname\uuuuu
:\uuuu qualname\uuuu=“工厂%s”%BaseClass__qualname_uu。这使得类创建期间的钩子(例如元类或
\uuuu init\u子类)可以看到“正确”的名称。我发现我还必须更改
\uuuu模块\uuuuu
以完全模拟类名。如果您需要使用
str()
中使用的名称,这是正确的答案。
Outer Outer
Inner Outer.Inner