2016-08-18 3 views
6

In Python2.7 kann dieser Code sehr gut funktionieren, __getattr__ in MetaTable wird ausgeführt. Aber in Python 3.5 funktioniert es nicht.__metaclass__ in Python3.5

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 

Aber in Python 3.5 Ich erhalte ein Attribut Fehler statt:

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' 

Antwort

13

Python 3 changed how you specify a metaclass wird __metaclass__ nicht mehr überprüft.

Verwenden metaclass=... in der Klasse Signatur:

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> 

Wenn Sie Unterstützung zur Verfügung stellen müssen für beide Python 2 und 3 in Ihrem Code-Basis, können Sie die six.with_metaclass() baseclass generator verwenden oder die @six.add_metaclass() class decorator, um die Metaklasse anzugeben.

+0

Der erste Weg kann funktionieren. Danke. – wyx

+0

Danke dafür. Es hat mein Lieblings-Plugin-System in Python 3 funktioniert. –

Verwandte Themen