In Python2.7 this code can work very well,__getattr__
inMetaTable
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 = aliasd = Tabled.student__s
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__sAttributeError: type object 'Table' has no attribute 'student__s'
1 Answer1
Python 3changed how you specify a metaclass,__metaclass__
is no longer checked.
Usemetaclass=...
in the classsignature:
class Table(object, metaclass=MetaTable):
Demo:
>>> 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>
If you need to provide support for both Python 2 and 3 in your codebase, you can use thesix.with_metaclass()
baseclass generator or the@six.add_metaclass()
class decorator to specify the metaclass.
answeredAug 18, 2016 at 8:26
Sign up to request clarification or add additional context in comments.
3 Comments
Kevin Shea
Thanks for this. It got my favourite plugin system working in python 3.
CodeFarmer
It would be possible to leave the existing __metaclass__ syntax in place
.python.org/dev/peps/pep-3115Martijn Pieters
@CodeFarmer: yes, but it doesn't do anything any more.
Explore related questions
See similar questions with these tags.