创建实例,我已经有类型了

31 投票
3 回答
27423 浏览
提问于 2025-04-17 07:55
class ClassA: pass
mytype = type(ClassA)

使用 mytype,我该如何创建 ClassA 的一个实例呢?

请注意,我并不想要这个作为我的答案 :)

instance = ClassA()

我知道在这个例子中,这就是你需要做的,但假设你有这个类型(mytype),你对它一无所知,而你需要创建它的一个实例。

我试着直接调用 mytype(),结果返回了一个错误,提示说 type() 需要 1 或 3 个参数。我想这些参数可能和你想传入创建对象的初始化方法的参数有关。

注意:我见过很多问题是关于如何根据一个表示其完整名称的字符串来创建对象的。这里我已经有一个类型,所以情况有点不同?我想?

我原本希望能做到类似于以下 .NET 代码的效果:

class A {}

class Program
{
    static void Main(string[] args)
    {
        Type type = typeof(A);

        // Given the type, I can create a new instance
        object new_instance = Activator.CreateInstance(type);
    }
}

我原以为在 Python 中,type(ClassA) 会返回一些东西,我可以用来创建 ClassA 的实例。看起来我对 Python 中的 type 理解错了。

3 个回答

3

lazy说,这个用type是做不到的。也许你可以试试下面这样的东西:

class ClassA: pass
myclass = ClassA
instance = myclass()
4

这个问题听起来有点奇怪。type(X)可以告诉你X的类型,但返回的结果并不包含关于X具体类的信息,就像type("abc")返回的是str,但并没有告诉你这个字符串的具体内容。

除非类X有一个自定义的元类,否则答案总是type,因为在Python中,type是默认的元类。所以在你的例子中,mytype is type,也就是说,它们是同一个对象。

你可以用type来检查一个对象的类型,如果只用一个参数的话;如果用三个参数,你可以动态创建一个类:

myclass = type('ClassB', (object,), {"class_attribute": 3.14})

假设一下mytype像你想的那样工作。记住,类型的实例就是一个类,就像类的实例就是一个对象一样。所以,就像(除了单例类)ClassA() is not ClassA()(每个实例都是独一无二的),mytype() is not mytype()——也就是说,每次你实例化这个类型时,应该得到一个不同的类。所以你无论如何都不会得到ClassA

为了更好地说明这个问题,你可以运行以下代码:

>>> type('A', (object,), {}) == type('A', (object,), {})
False

OP 编辑答案

在Python中,类是“第一类公民”,这和大多数编译语言不一样。这意味着你可以直接传递类;你不需要类似typeof的东西:

>>> class A(object): pass
... 
>>> B = A
>>> B()
<__main__.A object at 0xb781138c>
>>> def print_class_name(cls):
...     print cls.__name__
... 
>>> print_class_name(B)
A

这篇文章很好地解释了在Python中typeobject和对象实例之间的关系。

55

如果你使用一个新的样式类,这样做就可以了:

class ClassA(object):
    pass

o = ClassA()
mytype = type(o)
new_object = mytype()

撰写回答