在Python2.7这个代码可以很好地工作,__getattr__在MetaTable 运行。但是在Python 3中,它不起作用。
__getattr__
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
但是在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 3更改了您指定元类的方式,__metaclass__不再检查。
__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()基类生成器或@six.add_metaclass()类装饰器来指定元类。
six.with_metaclass()
@six.add_metaclass()