Метакласс является классом класса. Класс определяет, как экземпляр класса (т.е. объект) ведет себя, в то время как метакласс определяет, как класс ведет себя. Класс является экземпляром метакласса.
, В то время как в Python можно использовать произвольный callables для метаклассов (как [1 116] шоу Jerub), лучший подход должен сделать его самим фактическим классом. type
обычный метакласс в Python. type
самостоятельно класс, и это - свой собственный тип. Вы не будете в состоянии воссоздать что-то как type
просто в Python, но Python обманывает немного. Для создания собственного метакласса в Python, Вы действительно просто хотите разделить на подклассы type
.
метакласс А обычно используется в качестве фабрики классов. При создании объекта путем вызова класса Python создает новый класс (когда это выполняет оператор 'класса') путем вызова метакласса. Объединенный с нормальным __init__
и __new__
методы, метаклассы поэтому позволяют Вам делать 'дополнительные вещи' при создании класса, как регистрация нового класса с некоторым реестром или заменять класс чем-то еще полностью.
, Когда class
оператор выполняется, Python сначала выполняет тело class
оператор как нормальный блок кода. Получающееся пространство имен (dict) содержит атрибуты будущего класса. Метакласс определяется путем рассмотрения базовых классов будущего класса (метаклассы наследованы), в __metaclass__
атрибут будущего класса (если таковые имеются) или __metaclass__
глобальная переменная. Метакласс тогда называют с именем, основаниями и атрибутами класса для инстанцирования его.
Однако метаклассы на самом деле определяют тип класса, не только фабрика для него, таким образом, можно сделать намного больше с ними. Можно, например, определить нормальные методы на метаклассе. Эти методы метакласса похожи на classmethods, в котором их можно назвать на классе без экземпляра, но они также не как classmethods, в котором их нельзя назвать на экземпляре класса. type.__subclasses__()
пример метода на type
метакласс. Можно также определить нормальные 'волшебные' методы, как [1 113], __iter__
и __getattr__
, чтобы реализовать или измениться, как класс ведет себя.
Вот агрегированный пример остатков:
def make_hook(f):
"""Decorator to turn 'foo' method into '__foo__'"""
f.is_hook = 1
return f
class MyType(type):
def __new__(mcls, name, bases, attrs):
if name.startswith('None'):
return None
# Go over attributes and see if they should be renamed.
newattrs = {}
for attrname, attrvalue in attrs.iteritems():
if getattr(attrvalue, 'is_hook', 0):
newattrs['__%s__' % attrname] = attrvalue
else:
newattrs[attrname] = attrvalue
return super(MyType, mcls).__new__(mcls, name, bases, newattrs)
def __init__(self, name, bases, attrs):
super(MyType, self).__init__(name, bases, attrs)
# classregistry.register(self, self.interfaces)
print "Would register class %s now." % self
def __add__(self, other):
class AutoClass(self, other):
pass
return AutoClass
# Alternatively, to autogenerate the classname as well as the class:
# return type(self.__name__ + other.__name__, (self, other), {})
def unregister(self):
# classregistry.unregister(self)
print "Would unregister class %s now." % self
class MyObject:
__metaclass__ = MyType
class NoneSample(MyObject):
pass
# Will print "NoneType None"
print type(NoneSample), repr(NoneSample)
class Example(MyObject):
def __init__(self, value):
self.value = value
@make_hook
def add(self, other):
return self.__class__(self.value + other.value)
# Will unregister the class
Example.unregister()
inst = Example(10)
# Will fail with an AttributeError
#inst.unregister()
print inst + inst
class Sibling(MyObject):
pass
ExampleSibling = Example + Sibling
# ExampleSibling is now a subclass of both Example and Sibling (with no
# content of its own) although it will believe it's called 'AutoClass'
print ExampleSibling
print ExampleSibling.__mro__
Я думаю, для этого вам понадобится более низкий уровень, чем UDP.
Если бы я действительно хотел это сделать, я бы начал с загрузки сниффера пакетов / сетевого анализатора с открытым исходным кодом (на ум приходит Ethereal.com ) и просматривал источник, чтобы увидеть, как они читают пакеты.
Заглянув дальше, я нашел довольно много информации о захвате пакетов на tcpdump.org .
Извините, я не могу предоставить конкретные фрагменты кода, я всегда хотел привязать к определенному порту.
Вам нужно будет использовать WinPCap или аналогичный для снифф-пакетов на уровне ссылок, а затем фильтровать широковещательные рассылки UDP. Извините, я не думаю, что для этого есть API более высокого уровня.
Я сам нашел способ. Вот как это работает:
mainSocket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
mainSocket.Bind(new IPEndPoint(IPAddress.Parse("192.168.0.1"), 0));
mainSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true);
byte[] byTrue = new byte[4] { 1, 0, 0, 0 };
byte[] byOut = new byte[4] { 1, 0, 0, 0 };
// Socket.IOControl is analogous to the WSAIoctl method of Winsock 2
mainSocket.IOControl(IOControlCode.ReceiveAll, //Equivalent to SIO_RCVALL constant of Winsock 2
byTrue,
byOut);
//Start receiving the packets asynchronously
mainSocket.BeginReceive(byteData,0,byteData.Length,SocketFlags.None,new AsyncCallback(OnReceive),null);
В обработчике async я выполняю mainSocket.EndReceive (...), анализирую данные и запускаю новый BeginReceive, если требуется (управляемый извне многопоточного приемника).
Работает как Шарм. Кредиты принадлежат Хитешу Шарме ( http://www.codeproject.com/KB/IP/CSNetworkSniffer.aspx )