简体   繁体   English

关键字 arguments in python class inheritance

[英]Keyword arguments in python class inheritance

Hello I am recently looking about the metaclass in Python.您好,我最近正在寻找 Python 中的metaclass

I learned about we can attach a metaclass to a class in this way:我了解到我们可以通过这种方式将元类附加到 class:

class Metaclass(type):
    ...

class MyClass(metaclass=Metaclass):
    ...
  • The first question第一个问题

I wonder what's the principle of the keyword argument ( metaclass=... ) in the above example.我想知道上面例子中关键字参数( metaclass=... )的原理是什么。 There seems no description for that in the doc文档中似乎没有对此的描述

I know that there is keyword argument for a function, but I've never seen the form occurred in class inheritance.我知道 function 有一个关键字参数,但我从未见过这种形式出现在 class inheritance 中。

  • The second question第二个问题

We know that we can create a class using type() function in this way我们知道我们可以这样使用type() function 创建一个 class

cls = type(class_name, (base_class,), {func_name: func_ref})

Considering the metaclass=... form, how can I pass metaclass when creating class using type() instead of class keyword?考虑到metaclass=...形式,在使用type()而不是class关键字创建 class 时如何传递元类?

Thanks stackoverflowers!感谢 stackoverflowers!

In general, the keyword arguments used with a class statement are passed to __init_subclass__ , to be used however that function sees fit.通常,与class语句一起使用的关键字 arguments 会传递给__init_subclass__ ,但要使用 function 认为合适的关键字。 metaclass , however, is used by the code generator itself to determine what gets called in order to define the class.然而,代码生成器本身使用metaclass来确定调用什么来定义 class。

The metaclass is not an argument to be passed to a call to type ;元类不是要传递给type调用的参数; it is the callable that gets called instead of type .被调用的是可调用对象而不是type Very roughly speaking,非常粗略地说,

class MyClass(metaclass=Metaclass):
    ...

is turned into变成了

MyClass = Metaclass('MyClass', (), ...)

type is simply the default metaclass. type只是默认的元类。

(The gory details of how a class statement is executed can be found in Section 3.3.3 of the language documentation.) (有关如何执行class语句的详细信息,请参阅语言文档的第 3.3.3 节。)


Note that a metaclass does not have to be a subclass of type .请注意,元类不一定是类型的子type You can do truly horrific things with metaclasses, like你可以用元类做真正可怕的事情,比如

>>> class A(metaclass=lambda x, y, z: 3): pass
...
>>> type(A)
<class 'int'>
>>> A
3

It doesn't really matter what the metaclass returns , as long as it accepts 3 arguments.元类返回什么并不重要,只要它接受 3 arguments。

Please don't write actual code like this, though.不过,请不要编写这样的实际代码。 A class statement should produce something that at least resembles a type. class语句应该产生至少类似于一个类型的东西。


In some sense, class statements are less magical than other statements.在某种意义上, class语句没有其他语句那么神奇。 def statements, for example, can't be customized to produce something other than instances of function , and it's far harder to create a function object by calling types.FunctionType explicitly.例如, def语句无法定制为生成function实例以外的其他内容,并且通过显式调用types.FunctionType来创建function object 更难。

Yes I've looked this, but it doesn't provide something about principle of keyword argument in class inheritance, I am still confused是的,我看过这个,但它没有提供关于关键字参数原理的信息 class inheritance,我仍然很困惑

metaclass=... is not about inheritance. metaclass=...与 inheritance 无关。

Everything in Python is an object. So when you define a class MyClass , not only is MyClass() an object but the class MyClass itself is an object. Python 中的所有内容都是 object。因此,当您定义 class MyClass时,不仅MyClass()是 object,而且 class MyClass本身也是 object。

MyClass() is an instance of MyClass , simple enough. MyClass()MyClass的一个实例,非常简单。

But if MyClass is also an object, what class is it an instance of?但是如果MyClass也是一个 object,那么它是什么 class 的实例呢?

If you do nothing, the object (!) MyClass is an instance of the class type .如果您什么都不做,则 object (!) MyClass是 class type的一个实例。

If you do class MyClass(metaclass=Metaclass) then MyClass is an instance of Metaclass .如果你执行class MyClass(metaclass=Metaclass)那么MyClassMetaclass的一个实例。

Consider考虑

class Metaclass(type):
    pass

class MyClass1:
    pass

class MyClass2(metaclass=Metaclass):
    pass

Both MyClass1 and MyClass2 inherit from object and only object . MyClass1MyClass2都继承自object并且仅继承自object

>>> MyClass1.__mro__
(<class '__main__.MyClass1'>, <class 'object'>)
>>> MyClass2.__mro__
(<class '__main__.MyClass2'>, <class 'object'>)

But their types differ:但它们的类型不同:

>>> type(MyClass1)
<class 'type'>
>>> type(MyClass2)
<class '__main__.Metaclass'>

When would you need this?你什么时候需要这个? Usually, you don't.通常,你不会。 And when you do, you do the kind of metaprogramming where you already know the why and how.当你这样做时,你会进行那种你已经知道原因和方法的元编程。

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

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