代码之家  ›  专栏  ›  技术社区  ›  Max

用老方法抽象一门课是行不通的[复制]

  •  0
  • Max  · 技术社区  · 7 年前

    在Python2.7中,这个代码可以很好地工作, __getattr__ MetaTable 会跑的。但在Python 3中它不起作用。

    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
    

    但是在Python3.5中,我得到了一个属性错误:

    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'
    
    0 回复  |  直到 7 年前
        1
  •  34
  •   Mike Frysinger    7 年前

    蟒蛇3 changed how you specify a metaclass , __metaclass__ 不再检查。

    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>
    

    如果需要在代码库中同时支持Python2和3,可以使用 six.with_metaclass() baseclass generator 或者 @six.add_metaclass() class decorator