34

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'
Aran-Fey's user avatar
Aran-Fey
43.9k13 gold badges113 silver badges161 bronze badges
askedAug 18, 2016 at 8:23
wyx's user avatar

1 Answer1

57

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.

Mike Frysinger's user avatar
Mike Frysinger
3,1161 gold badge24 silver badges28 bronze badges
answeredAug 18, 2016 at 8:26
Martijn Pieters's user avatar
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for this. It got my favourite plugin system working in python 3.
It would be possible to leave the existing __metaclass__ syntax in place.python.org/dev/peps/pep-3115
@CodeFarmer: yes, but it doesn't do anything any more.

Your Answer

Sign up orlog in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

By clicking “Post Your Answer”, you agree to ourterms of service and acknowledge you have read ourprivacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.