gpt4 book ai didi

python - python2 和 python3 之间的可移植元类

转载 作者:太空狗 更新时间:2023-10-30 02:04:21 24 4
gpt4 key购买 nike

我正在尝试让 python2 程序在 python3 中运行,它具有以下 Meta 类定义。这在 Py2 上工作得很好。使其与 py2 和 py3 兼容的“最佳”方法是什么?

它在单元测试中失败了:

try:
raise Actor.DoesNotExist
except Actor.DoesNotExist:
pass

失败是:

AttributeError: type object 'Actor' has no attribute 'DoesNotExist'

基本元类定义是:

class MetaDocument(type):
def __new__(meta,name,bases,dct):

class DoesNotExist(BaseException):
pass

class MultipleDocumentsReturned(BaseException):
pass
dct['DoesNotExist'] = DoesNotExist
dct['MultipleDocumentsReturned'] = MultipleDocumentsReturned
class_type = type.__new__(meta, name, bases, dct)
if not class_type in document_classes:
if name == 'Document' and bases == (object,):
pass
else:
document_classes.append(class_type)
return class_type

class Document(object):
__metaclass__ = MetaDocument

最佳答案

您可以使用 MetaDocument() 元类作为工厂来生成类 替换 您的 Document 类,重新使用类属性:

class Document(object):
# various and sundry methods and attributes

body = vars(Document).copy()
body.pop('__dict__', None)
body.pop('__weakref__', None)

Document = MetaDocument(Document.__name__, Document.__bases__, body)

这不需要您手动构建第三个参数,即类主体。

你可以把它变成一个类装饰器:

def with_metaclass(mcls):
def decorator(cls):
body = vars(cls).copy()
# clean out class body
body.pop('__dict__', None)
body.pop('__weakref__', None)
return mcls(cls.__name__, cls.__bases__, body)
return decorator

然后用作:

@with_metaclass(MetaDocument)
class Document(object):
# various and sundry methods and attributes

或者,使用 six library为此:

@six.add_metaclass(MetaDocument)
class Document(object):

哪里@six.add_metaclass() decorator还处理您可能定义的任何 __slots__;我上面的简单版本没有。

6 还有一个 six.with_metaclass() base-class factory :

class Document(six.with_metaclass(MetaDocument)):

它向 MRO 中注入(inject)一个额外的基类。

关于python - python2 和 python3 之间的可移植元类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22409430/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com