Примечание, этот ответ для Python 2.x, как это было записано в 2008, метаклассы немного отличаются в 3.x.
Метаклассы являются секретным соусом, которые заставляют 'класс' работать. Метакласс по умолчанию для модернизированного объекта называют 'типом'.
class type(object)
| type(object) -> the object's type
| type(name, bases, dict) -> a new type
Метаклассы берут 3 args'. имя ', ' основания ' и' dict'
Вот - то, где секрет запускается. Ищите, куда имя, основания и dict прибывают из в этом определении класса в качестве примера.
class ThisIsTheName(Bases, Are, Here):
All_the_code_here
def doesIs(create, a):
dict
Позволяет, определяют метакласс, который продемонстрирует как' класс: ' вызовы это.
def test_metaclass(name, bases, dict):
print 'The Class Name is', name
print 'The Class Bases are', bases
print 'The dict has', len(dict), 'elems, the keys are', dict.keys()
return "yellow"
class TestName(object, None, int, 1):
__metaclass__ = test_metaclass
foo = 1
def baz(self, arr):
pass
print 'TestName = ', repr(TestName)
# output =>
The Class Name is TestName
The Class Bases are (<type 'object'>, None, <type 'int'>, 1)
The dict has 4 elems, the keys are ['baz', '__module__', 'foo', '__metaclass__']
TestName = 'yellow'
И теперь, пример, который на самом деле означает что-то, это автоматически сделает переменные в наборе "атрибутов" списка на классе и не установит ни на Один.
def init_attributes(name, bases, dict):
if 'attributes' in dict:
for attr in dict['attributes']:
dict[attr] = None
return type(name, bases, dict)
class Initialised(object):
__metaclass__ = init_attributes
attributes = ['foo', 'bar', 'baz']
print 'foo =>', Initialised.foo
# output=>
foo => None
Примечание, что волшебное поведение, что усиления 'Initalised' при наличии метакласса init_attributes
не передаются на подкласс Initalised.
Вот еще более конкретный пример, показывая, как можно разделить 'тип' на подклассы для создания метакласса, который выполняет действие, когда класс создается. Это довольно хитро:
class MetaSingleton(type):
instance = None
def __call__(cls, *args, **kw):
if cls.instance is None:
cls.instance = super(MetaSingleton, cls).__call__(*args, **kw)
return cls.instance
class Foo(object):
__metaclass__ = MetaSingleton
a = Foo()
b = Foo()
assert a is b
Из-за этого:
<!--[if lt IE 7]>
...
<![endif]-->
Это тег, распознаваемый только браузерами IE-типа, который на английском языке говорит: «Если версия браузера меньше IE7, покажите это».
... это особенность IE, которая позволяет настраивать таргетинг на разные версии их браузеров.
Этот код «спрашивает» браузер, какая у него версия (с помощью пользовательского агента браузера ). Если он «меньше» (lt) IE 7 (т.е. IE 6, IE 5, IE 4, IE 3, IE 2, IE 1), то он отображает HTML между двумя тегами.