__metaclass__在Python 3中 [英] __metaclass__ in Python 3

查看:155
本文介绍了__metaclass__在Python 3中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Python2.7中,此代码可以很好地工作,在MetaTable中的__getattr__ 会跑.但是在Python 3中,它不起作用.

In Python2.7 this code can work very well, __getattr__ in MetaTable will run. But in Python 3 it doesn't work.

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中,我得到了一个属性错误:

But in Python 3.5 I get an attribute error instead:

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 3 已更改您如何指定元类 ,不再检查__metaclass__.

Python 3 changed how you specify a metaclass, __metaclass__ is no longer checked.

在类签名中使用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()基类生成器 @six.add_metaclass()类修饰器来指定元类.

If you need to provide support for both Python 2 and 3 in your codebase, you can use the six.with_metaclass() baseclass generator or the @six.add_metaclass() class decorator to specify the metaclass.

这篇关于__metaclass__在Python 3中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆