EdУ меня тоже такой вопрос возник. На него автор ответил: “чтобы работало a = obj.blah; obj.blah = a; del obj.blah”.
Кстати, по-моему для вызова только __getattr__ переопределить достаточно. Зачем еще __setattr__ и __delattr__ переопределяются непонятно.
EdНе совсем верно. Тут нам надо отделить атрибуты класса-обёртки от атрибутов обёртываемого класса. У последнего могут быть одноименные не публичные методы. Поэтому приватные методы.
Атрибуты с двумя подчеркиваниями рекомендуется использовать для атрибутов, которые хочется скрыть от доступа классов-наследников . Для обычных не публичных атрибутов используется одно подчеркивание слева.
EdНо если не ловить исключение, то можно поток поломать. То есть, насколько я понимаю, программа может не завершиться. Поэтому я просто вместо pass у себя сделал вывод об ошибке в stderr.
Не нравится - это слишком легко сказано. Таким подходом закрываются любые ошибки в таким образом вызываемых функциях. Попробуйте в вашей функции написать какую-нибудь чушь, скажем bla-bla-bla и запустить. Разницы не заметите, хотя она банально не будет работать. И как такое отлаживать?
nerijusУ меня действительно маленький опыт работы с потоками в Python. Но я тут вижу только один поток, который обрабатывает очередь запросов. Где же тут каждый метод в отдельном потоке?
Вы уж меня простите но запускать каждый метод в новом потоке это просто кошмар.
nerijusКстати, чем-то похоже. И тоже ловят все исключения (если я правильно понял). Но выводят зачем-то в stdout.
Для решения таких задач, нужно создать thread pool и запихивать туда задачи (функции). А то что ты здесь пытаешься намудрить, очень похоже на отсутствие понятия что такое thread вообще. Вот посмотри пример: http://code.activestate.com/recipes/577187-python-thread-pool/ и перестань морочить себе голову со всякими враперами.
Kogroma = ThreadProxy(TestClass())
Но я тут вижу только один поток, который обрабатывает очередь запросов. Где же тут каждый метод в отдельном потоке?
KogromНу там простой пример. Обработку исключений можно поменять, только нужно помнить что например запись в файл должна быть thread-safe (и вообще исключения ловить в стиле “try except Exception, e” плохо).
Кстати, чем-то похоже. И тоже ловят все исключения (если я правильно понял). Но выводят зачем-то в stdout.
KogromЯ в курсе для чего переопределяют setattr и delattr, но не вижу применения им в данной задаче. Повторюсь, для вызова методов достаточно переопределить getattr. Кроме вызова методов я ничего в вашем коде не вижу. А иметь лишний код для того чтобы он просто был не считаю разумным.
У меня тоже такой вопрос возник. На него автор ответил: “чтобы работало a = obj.blah; obj.blah = a; del obj.blah”.
KogromХех :( Ну давайте смотреть код тогда. Похоже теоретически вас не переубедить.
Не совсем верно. Тут нам надо отделить атрибуты класса-обёртки от атрибутов обёртываемого класса. У последнего могут быть одноименные не публичные методы. Поэтому приватные методы
Но если не ловить исключение, то можно поток поломать. То есть, насколько я понимаю, программа может не завершиться. Поэтому я просто вместо pass у себя сделал вывод об ошибке в stderr.Я и не предлагал не ловить исключение. Я возражал против тупого игнорирования всех исключений.
nerijus“Так делать не надо” - слишком неопределенный совет. Вероятно, подразумевался совет: не следует запускать слишком много потоков. У меня такой объект в потоке один на всю программу, так что этот совет я учитываю.
a = ThreadProxy(TestClass())
b = ThreadProxy(TestClass())
Извини, не каждый метод, а каждый объект. Но все равно так делать не надо.
nerijusНу, а это у меня что? Декоратор в чистом виде, если говорим о паттернах GoF.
Если хочешь меньше спагетти, можешь прикрыть методы декоратором.
KogromКстати, все треды будут работать на одном core. Если это не то, чего хотелось, то можно попользоваться multiprocessing.
У меня действительно маленький опыт работы с потоками в Python. Но я тут вижу только один поток, который обрабатывает очередь запросов. Где же тут каждый метод в отдельном потоке?
EdВ какой данной задаче? То, что запускается, когда модуль является главным - это не задача, а тест работы. Причём не полный. Он нужен для того, чтобы человек, использующий использующий этот класс (точнее, модуль) мог быстрее понять о его предназначении.
Я в курсе для чего переопределяют setattr и delattr, но не вижу применения им в данной задаче.
EdОни вызываются:
ХПокажите мне, скажем, необходимость двух подчеркиваний перед вашим self.__requests, __obj, __worker.
Это не методы, вызываться через ваш прокси они не будут, даже если таковые и будут в ваших обертываемых классах.
attr = getattr(self.__obj, key)
if not callable(attr): return attr
EdОк. Почему методы с одним подчеркиванием вообще доступны? Гвидо ван Россум хотел сделать приятное быдлокодерам?
Теперь о методах. Возьмем __run. Вы серьезно думаете, что вызов приватного _run из обертываемого класса - это хороший дизайн? По-моему таким образом кроме публичных методов ничего не должно вызываться.
EdНу хоть в чём-то договорились :)
Я и не предлагал не ловить исключение. Я возражал против тупого игнорирования всех исключений.
EdЯ в курсе. Но меня это пока устраивает.
Кстати, все треды будут работать на одном core. Если это не то, чего хотелось, то можно попользоваться multiprocessing.
EdПохоже, что так. И с ходу я не вижу элегантного решения этой проблемы, ибо запускающая функция не должна дожидаться ответа. Можно передавать объект среди параметров, который будет получать результат. Я пока делаю так. Но это не очень красиво.
И еще одно - никак не обрабатываются возвращаемые значения вызываемых методов. То есть если кроме побочных эффектов интересует еще и результат, то вы его при таком подходе теряете.
KogromЧудесно. покажите как вы собираетесь использовать __setattr__ и __delattr__ для вашего класса. Я просто подумал, что цель - это вызвать метод объекта. Если вы собираетесь еще и назначать его атрибуты извне через этот прокси, то мой вопрос отпал как дурацкий. Да и вообще на основании чего мне делать выводы. Вы нигде не указали, что это неполный тест :)
В какой данной задаче? То, что запускается, когда модуль является главным - это не задача, а тест работы. Причём не полный. Он нужен для того, чтобы человек, использующий использующий этот класс (точнее, модуль) мог быстрее понять о его предназначении.
Они вызываются:Это вопрос реализации приоритетов. Можно сначала проверять атрибуты прокси, а потом уже проксируемого объекта и этой проблемы не будет.attr = getattr(self.__obj, key)
if not callable(attr): return attr
Ок. Почему методы с одним подчеркиванием вообще доступны? Гвидо ван Россум хотел сделать приятное быдлокодерам?Он хотел сделать язык нежестким и у него получилось. В смысле того, что отвественность лежит на программисте в конечном счете. Если кто-то хочет доступаться извне к внутренним переменным - это его решение. Незачем устраивать террор там, где он не нужен.
Ну хоть в чём-то договорились :)На самом деле мы уже о многом договорились, просто вы в пылу спора не замечаете :)