【问题标题】:__metaclass__ in Python 3Python 3 中的 __metaclass__
【发布时间】:2016-12-25 02:12:58
【问题描述】:

在 Python2.7 中这段代码可以很好地工作,__getattr__ in MetaTable 会跑。但在 Python 3 中它不起作用。

class MetaTable(type):
    def __getattr__(cls, key):
        temp = key.split("__")
        name = temp[0]
        alias = None

        if len(temp) > 1:
            alias = temp[1]

        return cls(name, alias)


class Table(object):
    __metaclass__ = MetaTable

    def __init__(self, name, alias=None):
        self._name = name
        self._alias = alias


d = Table
d.student__s

但在 Python 3.5 中,我得到了一个属性错误:

Traceback (most recent call last):
  File "/Users/wyx/project/python3/sql/dd.py", line 31, in <module>
    d.student__s
AttributeError: type object 'Table' has no attribute 'student__s'

【问题讨论】:

    标签: python metaclass


    【解决方案1】:

    不再检查 Python 3 changed how you specify a metaclass__metaclass__

    在类中使用metaclass=...签名

    class Table(object, metaclass=MetaTable):
    

    演示:

    >>> class MetaTable(type):
    ...     def __getattr__(cls, key):
    ...         temp = key.split("__")
    ...         name = temp[0]
    ...         alias = None
    ...         if len(temp) > 1:
    ...             alias = temp[1]
    ...         return cls(name, alias)
    ...
    >>> class Table(object, metaclass=MetaTable):
    ...     def __init__(self, name, alias=None):
    ...         self._name = name
    ...         self._alias = alias
    ...
    >>> d = Table
    >>> d.student__s
    <__main__.Table object at 0x10d7b56a0>
    

    如果您需要在代码库中同时支持 Python 2 和 3,可以使用 six.with_metaclass() baseclass generator@six.add_metaclass() class decorator 指定元类。

    【讨论】:

    • 谢谢。它让我最喜欢的插件系统在 python 3 中运行。
    • It would be possible to leave the existing __metaclass__ syntax in placepython.org/dev/peps/pep-3115
    • @CodeFarmer:是的,但它不再做任何事情了。
    猜你喜欢
    • 2011-12-04
    • 1970-01-01
    • 2010-12-22
    • 1970-01-01
    • 2018-05-28
    • 2019-02-15
    • 1970-01-01
    相关资源
    最近更新 更多