python - 从临时类继承的 Python 类
问题描述
当我试图弄清楚以下内容时,我陷入了困境codes
:
def with_metaclass(meta, base=object):
print("[2]")
return meta("NewBase", (base,), {})
class BaseForm(object):
def __init__(self, fields, prefix=''):
print(self.__class__)
def say(self):
print("BaseForm")
class FormMeta(type):
def __init__(cls, name, bases, attrs):
print("[3]: {!r}, {!r}, {!r}, {!r}, {!r}".format(cls, name, type(cls), bases, attrs))
type.__init__(cls, name, bases, attrs)
def __call__(cls, *args, **kwargs):
print("[4]: {!r}, {!r}".format(cls, type(cls)))
return type.__call__(cls, *args, **kwargs)
print("[1]")
class Form(with_metaclass(FormMeta, BaseForm)):
print("[5]")
def __init__(self):
NewBase.__init__(self)
print("[6]: {!r}, {!r}".format(self, type(self)))
# confused position
print(Form.__bases__)
# Form is based on NewBase, however, there is no NewBase
print(dir())
这是代码输出:
[1]
[2]
[3]: <class '__main__.NewBase'>, 'NewBase', <class '__main__.FormMeta'>, (<class '__main__.BaseForm'>,), {}
[5]
[3]: <class '__main__.Form'>, 'Form', <class '__main__.FormMeta'>, (<class '__main__.NewBase'>,), {'__module__': '__main__', '__qualname__': 'Form', '__init__': <function Form.__init__ at 0x7f6ad4d76f28>}
(<class '__main__.NewBase'>,)
['BaseForm', 'Form', 'FormMeta', '__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'with_metaclass']
就像我评论的那样,Form
是基于NewBase
,但是,主模块中没有一个NewBase
类。一个类的基类不可访问,是错误吗?但有趣的是,Form
仍然可以调用来自其父级的父级的方法。
解决方案
为了回答起见,我们一开始不需要 FormMeta 类。想象一下Form的定义如下:
class Form(with_metaclass(meta=type, base=BaseForm)):
# ...
该with_metaclass
调用只返回meta("NewBase", (base,), {})
,在本例中为 just type("NewBase", (base,), {})
,它创建了一个名为 的新类,该类NewBase
派生自base
(BaseForm
在本例中),没有其他方法。您可以在类型文档中阅读有关它的信息。
在这种FormMeta
情况下,元类什么也不做。它继承type
(这就是为什么它是一个元类),然后只是将它接收到的数据传递给type
,加上一些打印语句。所以基本上和上面一样。您可以在此处阅读有关元类的更多信息。
推荐阅读
- apache-kafka-streams - Kafka Streams with suppress() reprocessing changelog
- wordpress - 如何在 GCP VM 实例中配置 ftp 服务器?
- python - 熊猫数据框中的某些列是否有 3D 表或“列的列”?
- angular - RXJS - 等到两个 observables 都完成
- react-native - 如何更新 FlatList 项目的属性?
- c# - 无法将类型 vector3 转换为浮点数
- sql - 使用@@RowCount 进行多次更新
- c - 将指针数组分配给 void 类型转换指针如何工作?
- javascript - React/Redux:当它与 redux-form 结合时,有没有办法清除反应日期选择器?
- go - 如何在使用 GRPC 时提供文件