- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
以下代码无法编译;它说
NameError: name 'fields' is not defined
在最后一行。是因为 __new__
直到达到 fields
赋值后才被调用吗?我该怎么办?
class Meta(type):
def __new__(mcs, name, bases, attr):
attr['fields'] = {}
return type.__new__(mcs, name, bases, attr)
class A(metaclass = Meta):
def __init__(self, name):
pass
class B(A):
fields['key'] = 'value'
编辑:
我发现这不是时间问题;这是名字隐藏的问题。如果我改写 A.fields
就可以正常工作。
我想知道为什么我不能使用 fields
或 super().fields
。
最佳答案
fields['key'] = 'value'
在元类机制启动之前运行。
class foo(object):
var1 = 'bar'
def foobar(self):
pass
当 python 命中 class
时语句,它进入一个新的本地命名空间。
它评估 var1 = 'bar'
陈述。这相当于 locals()['var1'] = 'bar'
然后计算 def foobar
陈述。这相当于 locals()['var'] = the result of compiling the function
它然后通过locals()
,连同类名、继承的类和元类的元类 __new__
方法。在示例中,元类只是 type
.
然后退出新的本地命名空间并粘贴从 __new__
返回的类对象在名称为 foo
的外部命名空间中.
当您使用 A.fields
时,您的代码有效因为类 A
已经创建,因此上面的过程已经用你的 Meta
执行了安装 fields
在 A
.
您不能使用 super().fields
因为类名 B
未定义为在 super 运行时传递给 super。那就是你需要它是 super(B).fields
但是B
在类创建之后定义。
根据您对我对问题的评论的回复,这里有一些代码可以执行您想要的操作。
def MakeFields(**fields):
return fields
class Meta(type):
def __new__(mcs, name, bases, attr):
for base in bases:
if hasattr(base, 'fields'):
inherited = getattr(base, 'fields')
try:
attr['fields'].update(inherited)
except KeyError:
attr['fields'] = inherited
except ValueError:
pass
return type.__new__(mcs, name, bases, attr)
class A(metaclass=Meta):
fields = MakeFields(id='int',name='varchar')
class B(A):
fields = MakeFields(count='int')
class C(B):
pass
class Test(object):
fields = "asd"
class D(C, Test):
pass
print C.fields
print D.fields
关于python:元类中__new__的时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3723979/
为什么下面的代码会出错? class Foo: def __new__(cls, *args, **kwargs): print("Creating Instance")
Documentation for object.__new__(cls[, ...]) says: Called to create a new instance of class cls. __
编码异常类,我遇到了这个错误: TypeError: object.__new__(A) 不安全,使用 Exception.__new__() 这里有一个类似的问题: TypeError: objec
以下是使用 PyCharm Community Edition 中的 Tkinter 在 Python 3.0 中对 Conway 的生命游戏的不完整实现。 程序由四个文件组成: Cell.py:包含
阅读本文时:What is a metaclass in Python? ,我正在学习使用 __new__ 使用以下代码段:- class a(object): pass a.__new__(
前言 我想要具有以下属性的 2 个类 Interval 和 Segment: Interval 可以有 start 和 end 点,它们中的任何一个都可以被包含/排除(我已经使用必需的标志参数实现了这
我知道当我们通过 super 方法调用父方法时,我们可以忽略绑定(bind)方法中的“self”参数,如下所示: class Foo(object): def __init__(self):
假设以下代码: class NumStorage(object): def __new__(cls, *nargs): name = cls.__name__
嗨,我一直收到这个错误,我不知道如何避免。 我有以下代码: class retrieve_account_data(Thread): _account_queue = None _di
假设我有一些调用 __new__ 的类,我如何才能很好地使用 mro 并根据需要调用父类(super class)的 __new__(带参数),但不使用附加参数调用 object.__new__?例如
我正在尝试像这样深度复制我的 igraph 对象: copy.deepcopy(graph) 其中 graph 是 igraph 对象,一个只有几个顶点的完整图。但是我得到这个错误: Fi
假设我有以下代码用于处理个人和国家/地区之间的链接: from dataclasses import dataclass @dataclass class Country: iso2 : st
我知道类是元类的实例,并且 __new__ 在 __init__ 之前运行,因为,您必须在初始化它之前创建一个实例。 现在想象一下: import time class ConfigurationsM
使用Python元类A创建一个新类B。 当C继承B时,为什么调用A的__new__方法? class A(type): def __new__(cls, name, bases, attrs)
案例1: class Person: def __new__(cls, *args, **kwargs): print "called" return supe
我可以知道为什么 myClass1 和 myClass2 在覆盖 __new__() 方法时表现不同吗?推荐使用哪种方式来编写类,为什么?我认为 myClass1(): 甚至没有调用 __new__(
当__new__返回类的实例时,一切正常,我们可以毫无问题地创建子类: class A: def __new__(cls, p1, p2): self = object.__n
如何编写默认的 __new__ 并进行一些小的更改,如下所示: class A: def __new__(cls, *args, **kwargs): retval = sup
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 8 年前。 Improve this qu
我一直在努力理解__new__ 和元编程。所以我看了一下官方的 python 源代码。 http://hg.python.org/cpython/file/2.7/Lib/fractions.py 分
我是一名优秀的程序员,十分优秀!