Django 소스 기초 16-django에서 신호에 대한 학습 분석을 깊이 학습하다
프로젝트 개발의 측면에서django의 신호 처리 기술은 보조 기능에 속한다.절차가 뚜렷하지 않다.
django가 제공하는 신호는
class_prepared = Signal(providing_args=["class"])
pre_init = Signal(providing_args=["instance", "args", "kwargs"])
post_init = Signal(providing_args=["instance"])
pre_save = Signal(providing_args=["instance", "raw", "using", "update_fields"])
post_save = Signal(providing_args=["instance", "raw", "created", "using", "update_fields"])
pre_delete = Signal(providing_args=["instance", "using"])
post_delete = Signal(providing_args=["instance", "using"])
post_syncdb = Signal(providing_args=["class", "app", "created_models", "verbosity", "interactive"])
m2m_changed = Signal(providing_args=["action", "instance", "reverse", "model", "pk_set", "using"])
request_started = Signal()
request_finished = Signal()
got_request_exception = Signal(providing_args=["request"])
신호의 원리를 분석하다.알 수 있어.
신호 내부에서는 주로 Receiver와sender (None 허용) 의 키 조합을 통해 신호 슬롯을 저장합니다.
send가 신호를 보낼 때신호조 목록을 옮겨다니다.sender가 허용할지 여부를 판단합니다.허용되면 함수를 호출합니다.
한 가지 확실한 것은 신호가 단일 방식을 사용한다는 것이다.전체적인 유일성을 가져야 한다는 얘기다.너무 많이 사용하면 성능에 부담이 된다.그렇기 때문에 Django가 자체로 가지고 있는 것만 실현하면 된다.
다음은 뽑아낸 프레젠테이션 코드입니다.
from django.dispatch import saferef
import weakref
def _make_id(target):
if hasattr(target, '__func__'):
return (id(target.__self__), id(target.__func__))
return id(target)
import threading
WEAKREF_TYPES = (weakref.ReferenceType, saferef.BoundMethodWeakref)
class Signal(object):
def __init__(self):
self.receivers = []
self.lock = threading.Lock()
def connect(self, receiver, sender=None, weak=True, dispatch_uid=None):
import inspect
assert callable(receiver) , "Signal receivers must be callable."
try:
argspec = inspect.getargspec(receiver.__call__)
except (TypeError, AttributeError):
argspec = None
if argspec:
assert argspec[2] is not None, \
"Signal receivers must accept keyword arguments (**kwargs)."
if dispatch_uid:
lookup_key = (dispatch_uid, _make_id(sender))
else:
lookup_key = (_make_id(receiver), _make_id(sender))
if weak:
receiver = saferef.safeRef(receiver, onDelete=self._remove_receiver)
with self.lock:
for r_key, _ in self.receivers:
if r_key == lookup_key:
break
else:
self.receivers.append((lookup_key, receiver))
def disconnect(self, receiver=None, sender=None, weak=True, dispatch_uid=None):
if dispatch_uid:
loopup_key = (dispatch_uid, _make_id(sender))
else:
loopup_key = (_make_id(receiver), _make_id(sender))
with self.lock:
for index in xrange(len(self.receivers)):
(r_key, _) = self.receivers[index]
if r_key == loopup_key:
del self.receivers[index]
break
def has_listeners(self, sender=None):
return bool(self._live_receivers(_make_id(sender)))
def send(self, sender, **named):
responses = []
if not self.receivers:
return responses
for receiver in self._live_receivers(_make_id(sender)):
response = receiver(signal=self, sender=sender, **named)
responses.append((receiver, response))
return responses
def _live_receivers(self, senderkey):
none_senderkey = _make_id(None)
receivers = []
for (receiverKey, r_senderkey), receiver in self.receivers:
if r_senderkey == none_senderkey or r_senderkey == senderkey:
if isinstance(receiver, WEAKREF_TYPES):
receiver = receiver()
if receiver is not None:
receivers.append(receiver)
else:
receivers.append(receiver)
return receivers
def _remove_receiver(self, receiver):
with self.lock:
to_remove = []
for key, connected_receiver in self.receivers:
if connected_receiver == receiver:
to_remove.append(key)
for key in to_remove:
last_idx = len(self.receivers) - 1
for idx, (r_key, _) in enumerate(reversed(self.receivers)):
if r_key == key:
del self.receivers[last_idx - idx]
signal_demo = Signal()
def reset_queries(**kwargs):
print 'reset_querys [%s]' % str(kwargs)
signal_demo.connect(reset_queries)
class objDemo(object):
def click(self):
signal_demo.send(sender=self.__class__, request={"1":1})
obj = objDemo()
obj.click()
출력 인쇄
reset_querys [{'signal': <__main__.Signal object at 0x109be5290>, 'request': {'1': 1}, 'sender': <class '__main__.objDemo'>}]
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.