2014-12-11 2 views
1

Я пытаюсь понять, что делает дескриптор __get__ в коде ниже. Я написал весь учебник о __get__, все еще не могу понять, что здесь происходит.Дескриптор __get__ из метода

class A: 
    def __init__(self, socket, address=None): 
     self.sock = socket 
     self.address = address 
     self.verbose = True 

class B(): 
    def __init__(self): 
     self.clients = [] 
     self.slaves = [] 
     self.pending_tasks = [] 
     self.running_tasks = {} 
     self.finished_tasks = {} 


class C(B): 
    def __init__(self, *args, **kwargs): 
     super(C, self).__init__(*args, **kwargs) 


    def handle_new_connection(self, socket, address): 
     link = A(socket, address) 

    def bind(self, host, port): 
     handle = self.handle_new_connection.__get__(self, C) 

if __name__ == "__main__": 
    m = C() 
    m.bind('0.0.0.0', 6666) 

Что __get__ делает в методе связывания?

+0

Это * полностью избыточно *, поскольку 'self.handle_new_connection' делает привязку * уже *. –

+0

Переменная дескриптора отправляется на gevent.server.StreamServer. Я полагаю, что __get__ в дескрипторе возвращает носок и адрес из NetLink? Я прав? – user3648963

ответ

2

Звонок __get__ является излишним и бесполезным. Метод уже связан, все __get__ вызов делает привязать его снова:

>>> m = C() 
>>> m 
<__main__.C object at 0x10b2cbeb8> 
>>> m.handle_new_connection 
<bound method C.handle_new_connection of <__main__.C object at 0x10b2cbeb8>> 
>>> m.handle_new_connection.__get__(m, C) 
<bound method C.handle_new_connection of <__main__.C object at 0x10b2cbeb8>> 

Обратите внимание, как __get__ вызов метода на уже связанный объект метод возвращается сам связанный объект метода; здесь ничего не изменилось.

Единственная причина, по которой я могу подумать о переходе через этот обруч (кроме понимания того, что поиск метода Python уже вызвал дескриптор функции), заключается в возможности вызвать метод как метод класса (путем передачи в явный первый аргумент, который не является экземпляром, но класс):

>>> C.handle_new_connection 
<function C.handle_new_connection at 0x10b5e32f0> 
>>> C.handle_new_connection.__get__(C, C) 
<bound method type.handle_new_connection of <class '__main__.C'>> 
>>> C.bind(C, '0.0.0.0', 6666) 

, потому что в этом случае self.handle_new_connection решает в оригинальной несвязанной функции.

+0

Спасибо! Большое спасибо! – user3648963

+0

Код по-прежнему плохо написан. Было бы разумнее просто объявить 'handle_new_connection' как' @ classmethod' (или даже '@ staticmethod') в первую очередь. – Kevin

+0

@Kevin: совершенно. Я склоняюсь к объяснению «не понимаю, что они делают». –

Смежные вопросы