__metaclass__在Python 3中 [英] __metaclass__ in 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屋!