Python 食谱 recipe9.14 讨论
Python Cookbook recipe9.14 Discussion
当我阅读 Python Cookbook recipe 9.14 讨论时,它说我必须在制作最终的 class 对象时将 OrderedDict 转换为字典实例。我必须这样做还是使用 OrderedDict 可以?
我试过了,将 OrderedDict 传递给类型构造函数,它没有引发任何异常
class OrderedMeta(type):
def __new__(cls, clsname, bases, attr_dict):
order = []
for name, value in attr_dict.items():
if isinstance(value, Typed):
value._name = name
order.append(name)
attr_dict['_order'] = order
return type.__new__(cls, clsname, bases, attr_dict)
@classmethod
def __prepare__(cls, clsname, bases):
return OrderedDict()
书中的代码
class OrderedMeta(type):
def __new__(cls, clsname, bases, attr_dict):
d = dict(attr_dict)
order = []
for name, value in attr_dict.items():
if isinstance(value, Typed):
value._name = name
order.append(name)
d['_order'] = order
return type.__new__(cls, clsname, bases, d)
@classmethod
def __prepare__(cls, clsname, bases):
return OrderedDict()
enter image description here
你必须这样做,出于某些原因,David Beasley 没有进一步详细说明
"it may cause problems if you don't"
在他的 2013 tutorial Python 3 Metaprogramming 中,大约 1 小时 30 分钟。
自该教程以来,python 3.6 引入了保留其顺序的词典,因此您可以安全地忽略此食谱中 ordereddict
的使用。
不,不需要。
type.__new__
可以采用任何映射 - 甚至可能使用比完整映射协议更少的方法 - __iter__
、__len__
和 __getitem__
就足够了。
这可能是有效的,因为 Python 3.0 - 食谱的作者简单地使用了 "safe road",因为他不确定将 non-native dict 传递给 type.__new__
并在 OrderedDict 上调用 dict
无论如何都是一行简单的代码。
但是允许在 __prepare__
中使用任何自定义映射然后不在 type.__new__
上接受相同的映射没有多大意义 - 也就是说,你甚至不如果您只需要自定义映射,则需要在您的 metaclass 上使用 __new__
方法 - 只需 __prepare__
方法。
就是说,这个特殊的配方现在已经过时了,因为 Python 3.6 中使用的词典在 class 中默认排序(并且从 Python 3.7 开始,所有 Python字典默认排序)。
当我阅读 Python Cookbook recipe 9.14 讨论时,它说我必须在制作最终的 class 对象时将 OrderedDict 转换为字典实例。我必须这样做还是使用 OrderedDict 可以?
我试过了,将 OrderedDict 传递给类型构造函数,它没有引发任何异常
class OrderedMeta(type):
def __new__(cls, clsname, bases, attr_dict):
order = []
for name, value in attr_dict.items():
if isinstance(value, Typed):
value._name = name
order.append(name)
attr_dict['_order'] = order
return type.__new__(cls, clsname, bases, attr_dict)
@classmethod
def __prepare__(cls, clsname, bases):
return OrderedDict()
书中的代码
class OrderedMeta(type):
def __new__(cls, clsname, bases, attr_dict):
d = dict(attr_dict)
order = []
for name, value in attr_dict.items():
if isinstance(value, Typed):
value._name = name
order.append(name)
d['_order'] = order
return type.__new__(cls, clsname, bases, d)
@classmethod
def __prepare__(cls, clsname, bases):
return OrderedDict()
enter image description here
你必须这样做,出于某些原因,David Beasley 没有进一步详细说明
"it may cause problems if you don't"
在他的 2013 tutorial Python 3 Metaprogramming 中,大约 1 小时 30 分钟。
自该教程以来,python 3.6 引入了保留其顺序的词典,因此您可以安全地忽略此食谱中 ordereddict
的使用。
不,不需要。
type.__new__
可以采用任何映射 - 甚至可能使用比完整映射协议更少的方法 - __iter__
、__len__
和 __getitem__
就足够了。
这可能是有效的,因为 Python 3.0 - 食谱的作者简单地使用了 "safe road",因为他不确定将 non-native dict 传递给 type.__new__
并在 OrderedDict 上调用 dict
无论如何都是一行简单的代码。
但是允许在 __prepare__
中使用任何自定义映射然后不在 type.__new__
上接受相同的映射没有多大意义 - 也就是说,你甚至不如果您只需要自定义映射,则需要在您的 metaclass 上使用 __new__
方法 - 只需 __prepare__
方法。
就是说,这个特殊的配方现在已经过时了,因为 Python 3.6 中使用的词典在 class 中默认排序(并且从 Python 3.7 开始,所有 Python字典默认排序)。