方法的描述符__get__

时间:2014-12-11 10:54:51

标签: python

我试图了解__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__在绑定方法中做了什么?

1 个答案:

答案 0 :(得分: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会解析为原始的未绑定函数。