2016-08-18 23 views
6

W Python2.7 ten kod może działać bardzo dobrze, __getattr__ w MetaTable będzie działać. Ale w Pythonie 3.5 to nie działa.__metaclass__ w 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 

Ale w Pythonie 3.5 pojawia się błąd atrybutu Zamiast:

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' 

Odpowiedz

13

Python 3 changed how you specify a metaclass, __metaclass__ nie jest zaznaczona.

Zastosowanie metaclass=... w klasie podpisu:

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> 

Jeśli trzeba zapewnić wsparcie zarówno dla Pythona 2 i 3 w swoim kodzie, można użyć six.with_metaclass() baseclass generator lub @six.add_metaclass() class decorator, aby określić metaclass.

+0

Pierwszy sposób może działać. Dzięki. – wyx

+0

Dzięki za to. Dostał mój ulubiony system wtyczek działający w pythonie 3. –