... при условии, что существует некоторое максимальное количество гнезд, с которыми вы были бы счастливы остановиться.
Позвольте мне объяснить.
@ torsten-marek прав, что регулярное выражение не может проверять вложенные шаблоны, подобные этому, но возможно определить вложенный шаблон регулярного выражения, который позволит вам захватите вложенные структуры, подобные этому , до некоторой максимальной глубины . Я создал один, чтобы записать комментарии в формате EBNF ( попробуйте здесь ), например:
(* This is a comment (* this is nested inside (* another level! *) hey *) yo *)
Регулярное выражение (для комментариев с одной глубиной ) является следующим:
m{1} = \(+\*+(?:[^*(]|(?:\*+[^)*])|(?:\(+[^*(]))*\*+\)+
Это может быть легко адаптировано для ваших целей, заменив \(+\*+
и \*+\)+
на {
и }
и заменив все между простыми [^{}]
:
p{1} = \{(?:[^{}])*\}
( Вот ссылка , чтобы попробовать это.)
Чтобы вложить, просто разрешите этот шаблон внутри самого блока:
p{2} = \{(?:(?:p{1})|(?:[^{}]))*\}
...or...
p{2} = \{(?:(?:\{(?:[^{}])*\})|(?:[^{}]))*\}
Чтобы найти тройные вложенные блоки, используйте:
p{3} = \{(?:(?:p{2})|(?:[^{}]))*\}
...or...
p{3} = \{(?:(?:\{(?:(?:\{(?:[^{}])*\})|(?:[^{}]))*\})|(?:[^{}]))*\}
Появился четкий шаблон. Чтобы найти комментарии, вложенные в глубину N
, просто используйте регулярное выражение:
p{N} = \{(?:(?:p{N-1})|(?:[^{}]))*\}
where N > 1 and
p{1} = \{(?:[^{}])*\}
Сценарий можно записать для рекурсивного генерации этих регулярных выражений, но это выходит за рамки того, для чего мне это нужно. (Это остается как упражнение для читателя.
У вас нет неявного доступа к атрибутам внутри методов в Python.
Голова имя типа currentid
в строке:
del connections[currentid]
всегда ищет имя в области локальных функций, затем в каждой области охватывающей функции, перед тем, как попробовать глобальную область модуля (а затем посмотрите на встроенные вложения в качестве последнего средства). currentid
- это атрибут класса, который не будет найден ни в одном из этих областей.
Чтобы найти атрибут в Python, вам всегда нужно указать объект для просмотра. Хотя протокол поиска означает, что объект необязательно должен иметь сам атрибут; поиск атрибута вернется к классу указанного вами объекта (и базовые классы, если наследование задействовано).
Итак, это сработает:
del connections[self.currentid]
Однако I не думайте, что остальная часть вашего кода делает то, что вы думаете. Эта строка в методе open
:
currentid = global_counter
не устанавливает атрибут currentid
вашего объекта SocketHandler
. При назначении головому имени всегда присваивает локальную переменную, если вы явно не объявляете ее global
(вы, похоже, знаете об этом, так как вы использовали ключевое слово global
). Таким образом, в методе open
currentid
является локальной переменной функции; его значение теряется в конце метода open
.
На самом деле, ваши SocketHandler
объекты вообще не имеют атрибута currentid
(если только нет кода, который вы нам не показали ). Помещение currentid = 0
в блок класса не дает всем экземплярам SocketHandler
атрибуту currentid
. Это дает SocketHandler
класс самому атрибуту currentid
; это так же, как блок def open(self):
создает атрибут open
(сохраняющий функцию) для объекта класса, а не для каждого отдельного экземпляра.
Чтение self.currentid
в методе on_close
не будет выполнено найти атрибут currentid
в объекте self
, поэтому Python будет смотреть на класс self
, который является SocketHandler
. Этот объект имеет значение currentid
, поэтому результат чтения self.currentid
будет 0
, независимо от того, вы ранее выполняли open
на этом SocketHandler
.
Если вы хотели сохранить currentid
в качестве переменной экземпляра в каждом SocketHandler
, тогда строка в open
должна быть:
self.currentid = global_counter
Это назначает currentid
атрибута объекта, на который ссылается self
. Вам также потребуется изменить все остальные ссылки на currentid
в ваших методах на self.currentid
.
currentid
- атрибут экземпляра, поэтому используйте self.currentid
вместо currentid
:
def on_close(self):
global connections
print "WebSocket " + str(self.currentid) + " closed"
del connections[self.currentid]
currentid
должен быть self.currentid
, поскольку это переменная класса.
open
? И всегда ли on_close
метод del connections[0]
?
– Ben
8 October 2012 в 23:23