2013-08-29 11 views

Odpowiedz

52

with_metaclass() jest funkcją fabryki klasy narzędzie dostarczane przez six library aby łatwiej rozwijać kod zarówno Python 2 i 3.

Tworzy klasę bazową o określonej klasie meta dla ciebie, kompatybilny z wersja Pythona, na którym uruchamiasz kod.

Cytując z dokumentacji:

Tworzenie nowej klasy z klasy bazowej podstawy i metaklasa metaklasą. Jest przeznaczony do stosowania w deklaracji klasy tak:

from six import with_metaclass 

class Meta(type): 
    pass 

class Base(object): 
    pass 

class MyClass(with_metaclass(Meta, Base)): 
    pass 

Jest to konieczne, ponieważ składnia aby dołączyć metaklasa zmieniło między Python 2 i 3:

Pythonie 2:

class MyClass(object): 
    __metaclass__ = Meta 

Pythona 3:

class MyClass(metaclass=Meta): 
    pass 

with_metaclass() Funkcja korzysta z faktu, że metaclasy są a) dziedziczone przez podklasy, oraz b) Metaclass może być użyty do generowania nowych klas; skutecznie tworzy nową klasę bazową za pomocą metaklasa jako fabryka generować pustą klasę:

def with_metaclass(meta, *bases): 
    """Create a base class with a metaclass.""" 
    return meta("NewBase", bases, {}) 

metaklasa klasy NewBase bazowej jest meta, zarówno w Pythonie 2 i 3.

+2

Aby wyjaśnić, w sześciu, składni (w celu dopasowania zachowania Pythona 2 i 3 powyżej): 'class MyClass (with_metaclass (Meta, object)): pass' (gdzie obiekt jest opcjonalny). –

12

UPDATE: funkcja six.with_metaclass() została następnie opatrzona wariantem dekoratora, tj. @six.add_metaclass(). Ta aktualizacja rozwiązuje niektóre problemy mro związane z obiektami podstawowymi. Nowy dekorator będzie stosowana w sposób następujący:

import six 

@six.add_metaclass(Meta) 
class MyClass(Base): 
    pass 

Here are the patch notes i here is a similar, detailed example and explanation za korzystanie alternatywę dekorator.