简体   繁体   English

Python:类实例是类

[英]Python: Class instances are classes

Is it possible to create a class whose instances are classes? 是否可以创建实例为类的类?

At first it seemed possible, but I wondered if this would actually be possible without any external interference. 乍一看似乎可行,但我想知道这是否有可能在没有任何外部干扰的情况下实现。 Eg: 例如:

NewClass = ClassClass(someArgs)
instance = NewClass(someOtherArgs)

Is this possible? 这可能吗? If so, how would it structurally work? 如果是这样,它将在结构上如何运作? Is this even useful? 这甚至有用吗?

If you check the type of 1 you get type(1) == int . 如果检查1的类型,则得到type(1) == int If you check the type of int you get type(int) == type . 如果检查int的类型,则会得到type(int) == type

A class whose instances are classes is called a metaclass and in Python you create metaclasses by subclassing type . 一个实例为类的类称为元类 ,在Python中,您可以通过子类化type创建元类。

class ClassClass(type):
    pass

Technically collections.namedtuple is a metaclass, but it's actually cheating . 从技术上说, collections.namedtuple是一个元类,但实际上是作弊行为

There's a great PyCon talk by David Beazly about metaprogramming in Python . David Beazly在PyCon上有一个关于Python元编程的精彩演讲 It's long, but very interesting. 很长,但是很有趣。 He starts talking about metaclasses around the 27 minute mark. 他开始谈论27分钟左右的元类。

You're looking for metaclasses: 您正在寻找元类:

class Foo(type):
    # Foo is a subclass of type and just like instances of type are
    # classes, instances of Foo are classes.
    pass

class Bar(object):
    # The Bar class is an instance of Foo
    __metaclass__ = Foo

# You can also create instances of Foo dynamically.
Bar = Foo("Bar", (object,), {})

More on metaclasses. 有关元类的更多信息。

From the Python help: 从Python帮助中:

type(name, bases, dict) -> a new type

So lets create a simple class: 因此,让我们创建一个简单的类:

Dog = type('Dog', (object,), {})

And now you can create a dog: 现在您可以创建一条狗:

fido = Dog()

If you literally want a class that creates classes, you can do it, by extending type... Honestly I have no idea what you want it for, but here it is: 如果您确实想要一个可以创建类的类,则可以通过扩展类型来实现……老实说,我不知道您想要的是什么,但是这里是:

class ClassMaker(type):
    def __new__(self, name):
        return type(name, (object,), {})

NewClass = ClassMaker('NewClass')
print NewClass

In (modern) python, classes are first order objects. 在(现代)python中,类是一阶对象。 This is easy to verify by accessing a class' __class__ property: 这很容易通过访问类的__class__属性来验证:

class A:
    pass

print(A.__class__)
-> <class 'type'>

Note that type 's class is also type : 请注意, type的类也是type

print(type.__class__)
-> <class 'type'>

It is possible to actually derive from type : 实际上可以从type派生:

class A:
    def do(self):
       print("DOING")


class mytype(type):
    def __new__(cls, *args, **kwargs):
        return type.__new__(cls, 'mytype', cls.__bases__, {})

    def __init__(self):
        return type.__init__(self, 'mytype', self.__class__.__bases__, {})

    def __call__(self, *args, **kwargs):
        return A(*args, **kwargs)

aClass = mytype()
-> <class '__main__.mytype'>
aObj = aClass()
print(aObj)
-> <__main__.A object at 0xdeadbeaf>
aObj.do()
-> DOING

However, with proper metaclasses I do not see a good reason jumping through such hoops. 但是,对于正确的元类,我看不出有充分的理由跳过这些麻烦。 Even metaclasses are only needed in special cases. 仅在特殊情况下才需要元类。 Most often, a factory method that returns a class object is sufficient: 通常,返回类对象的工厂方法就足够了:

def ClassClass():
    return A

aClass = ClassClass()
aObj = aClass()

Syntax is the same and if the only operation on the factory is instantiation, there is no difference. 语法是相同的,并且如果工厂中唯一的操作是实例化,则没有区别。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM