关于python:Python3中的__ metaclass__

__metaclass__ in Python3.5

在python2.7中,这个代码可以很好地工作,__getattr__MetaTable中。将运行。但在Python3.5中,它不起作用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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中,我得到了一个属性错误:

1
2
3
4
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__

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

1
class Table(object, metaclass=MetaTable):

演示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> 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()类修饰器来指定元类。